【问题标题】:Getting input in Kattis challenges - readline js在 Kattis 挑战中获得输入 - readline js
【发布时间】:2020-06-14 01:44:36
【问题描述】:

我正在挑战 Kattis -

https://open.kattis.com/problems/bookingaroom

基本上,我得到初始输入 - 比如说 6、4

我必须将该输入存储在某处,然后请求另一个 x 输入,其中 x = 第一个值,即。 6. 这些输入存储在其他地方的数组数组中。

我尝试了很多不同的东西,但要么我最初存储的值(6 和 4)发生了变化,要么它对其余的输入进行了过多的迭代。

我发现他们网站上的文档很糟糕。

https://open.kattis.com/help/javascript - 以 nodeJS 为例

我的代码尝试:

rl.question("initial", answer => {
  let nums = answer.split(" ");
  numberKittens = parseInt(nums[0]);
  spareBeds = parseInt(nums[1]);
  console.log("spare be", spareBeds);
  console.log("num of kit", numberKittens);
  rl.on(
    (numberKittens,
    answer => {
      let first = answer.split(" ");
      initialValue.push([parseInt(first[1]), parseInt(first[0])]);
      console.log("initial val", initialValue);
    })enter code here
  );
});

初始部分工作正常,但永远不会到达 rl.on 部分并一直要求输入

尝试二

rl.on("line", line => {
  let nums = line.split(" ");
  numberKittens = parseInt(nums[0]);
  spareBeds = parseInt(nums[1]);
  let first = line.split(" ");
  let initialValue = [];
  initialValue.push([parseInt(first[1]), parseInt(first[0])]);
})

每次都改变numberKittens和spasteBeds,弄乱了迭代

编辑:基本上,我想在 GO 中做这样的事情:

    fmt.Scanln(&numOfKittens, &numOfBeds)

    for i := 1; i <= numOfKittens; i++ {
        fmt.Scanln(&arrivalDate, &departureDate)
        fmt.Println(arrivalDate, departureDate)
}

【问题讨论】:

    标签: javascript node.js readline kattis


    【解决方案1】:

    由于readline 的异步回调 API,Kattis 的 Node 设置非常棘手。我通常使用promises,然后使用splitmap+ 来解析相关输入,因为通常涉及数字。然而,Kattis 会流式传输 readline 的 "line" 事件,然后在流式结束时触发文件结束 "close" 事件,而这些对于 Promise 来说并不容易使用。

    这是高级概述:

    const readline = require("readline");
    
    const rl = readline.createInterface({
      input: process.stdin,
      output: process.stdout,
    });
    
    rl.once("line", line => {
      // collect line 1, the preamble data
    
      rl.on("line", line => {
          // parse a line of the body data
        })
        .on("close", () => {
          // all data has been read
          // print the solution
        })
      ;
    });
    

    这是一个适用于booking a room 问题的示例:

    const readline = require("readline");
    
    const rl = readline.createInterface({
      input: process.stdin,
      output: process.stdout,
    });
    
    rl.once("line", line => {
      // collect line 1, the preamble data
      const rooms = [];
      const [r, n] = line.split(/ +/).map(Number);
      rl.on("line", line => {
          // parse a line of the body data
          rooms.push(+line);
        })
        .on("close", () => {
          // all data has been read
          // print the solution
          if (r === n) {
            console.log("too late");
          }
          else {
            for (let i = 1; i <= r; i++) {
              if (!rooms.includes(i)) {
                console.log(i);
                break;
              }
            }
          }
        })
      ;
    });
    

    如果序言多于一行,或者您不喜欢嵌套,则可以使用处理程序的数组或对象,其中每个索引都是该特定行的处理程序:

    const readline = require("readline");
    
    const rl = readline.createInterface({
      input: process.stdin,
      output: process.stdout,
    });
    
    let r;
    let n;
    const rooms = [];
    
    const handlers = [
      line => { // handler for line 0
        [r, n] = line.split(/ +/).map(Number);
      },
    
      /* add more handlers as needed, for lines 2, 3... */
    
      // handler for all remaining lines
      line => rooms.push(+line),
    ];
    let lines = 0;
    
    rl.on("line", line => {
        handlers[Math.min(lines++, handlers.length - 1)](line);
      })
      .on("close", () => {
        // print the solution
        if (r === n) {
          console.log("too late");
        }
        else {
          for (let i = 1; i <= r; i++) {
            if (!rooms.includes(i)) {
              console.log(i);
              break;
            }
          }
        }
      })
    ;
    

    这不如承诺或允许阻塞输入的语言好,但它可以完成工作。

    有关使用n 作为计数器来确定何时打印最终解决方案而不是监听"close" 事件的类似方法,请参见this gist。我还没有看到任何需要这样做的问题——Kattis 通常似乎会发送 EOF,但我使用 Kattis 的次数还不够多,无法知道我的提议总是有效的。

    在许多问题上,您不需要在最后汇总最终结果,因此您可以跳过.close() 并在结果流入您的正文数据的"line" 处理程序时打印结果。

    【讨论】:

      【解决方案2】:

      根据我对任务的理解,我会做这样的事情:

      let a, b;
      
      rl.on('init', (line) => { 
         const nums = line.split(' '); 
         a = parseInt(nums[0]); 
         b = parseInt(nums[1]); 
      });
      
      //next part
      const nextAnswers = [...Array(a)].map((_,i)=>{
         let answer;
         rl.on(`Next answer N:${i + 1}:`, a => (answer = a));    
         return parseInt(answer);
      })
      

      【讨论】:

      • 这不会像How to return the response from an asynchronous call 中描述的那样工作。您必须返回一个解析为answerab 的承诺(Array(a) 将在a = parseInt(nums[0]) 之前运行,return parseInt(answer) 将在answer = a 之前运行)。只使用回调可能更容易。此外,Next answer... 应该是事件名称,而不是提示字符串。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-09-23
      • 1970-01-01
      • 2023-02-15
      • 2021-01-31
      • 2019-06-17
      • 2019-03-30
      相关资源
      最近更新 更多