首页 > 解决方案 > 在 Kattis 挑战中获得输入 - readline js

问题描述

我正在做一个 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 和 SpareBeds,弄乱了迭代

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

    fmt.Scanln(&numOfKittens, &numOfBeds)

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

标签: javascriptnode.jsreadline

解决方案


由于readline. 我通常会使用promises,然后使用split, mapand+来解析相关的输入,因为通常会涉及到数字。然而,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
    })
  ;
});

这是一个适用于预订房间问题的示例:

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"事件。我还没有看到任何需要这样做的问题——Kattis 通常似乎会发送 EOF,但我使用 Kattis 的次数还不够多,无法知道我的提议总是有效的。

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


推荐阅读