Learn JavaScript

lesson ৭ / ৯ · type, operator আর coercion: '5' + 2 কেন 7 না

Module ২ · type, operator আর coercion: '5' + 2 কেন 7 না

Problem: type আর coercion

FreeProblem

এই lesson-এ যা শিখবে

  • প্রতিটা value ঠিক reader দিয়ে পড়তে পারবে: সংখ্যার জন্য nextInt(), text-এর জন্য next(), নিখুঁত বড় পূর্ণসংখ্যার জন্য BigInt(next()), আর ফাঁকা লাইনের জন্য lines variant।
  • প্রতিটা number ঠিক JavaScript যেভাবে print করে সেভাবে print করতে পারবে, আর বুঝিয়ে বলতে পারবে -0 কেন 0 হয়ে print হয় আর 0.1 + 0.2 কেন 17টা অঙ্ক দেখায়।
  • Submit করার আগে hidden test যে কিনারাগুলো ধরে সেগুলো নিজেই test করতে পারবে: -0, NaN, Infinity, একটা ফাঁকা লাইন আর সবচেয়ে বড় safe integer।

দশটা problem, Node 22-এ hidden test দিয়ে grade হয়, মানে Playground যে JavaScript চালায় সেটাই। এর আটটার সাথে এই module-এর lesson-গুলোতেই দেখা হয়েছে, আর bigint-sum ছিল Interview Pack-এ। দুটো নতুন, messy-measurements আর truthy-or-falsy, আর দুটোই মাঝারি।

Problem 1, 2 আর 4 (sum-and-join, clean-numbers আর largest-of-three) সবার জন্য free। বাকি সাতটা Pro problem: প্রতিটা problem আলাদা করে lock করার ব্যবস্থা আসবে পরের একটা release-এ, আর তার আগ পর্যন্ত দশটাই খোলা। Module test-এ দুটো problem আছে, calculator আর clean-numbers, তাই এ দুটো এখানে আগে সমাধান করে রাখা কাজের।

Bob sample পড়ে, sample যেটা print করে এমন প্রথম program-টা লিখে submit করে দেয়। Zara sample-এর দিকে তাকানোর আগেই নিজের program-কে খাওয়ায় -0, NaN আর একটা ফাঁকা লাইন। এই set-এর প্রতিটা hidden test এমন একটা value, যাকে coercion নিজের মতো করে সামলায়, তাই এখানে নম্বর আনে Zara-র অভ্যাসটাই।

সংখ্যার জন্য nextInt(), text-এর জন্য next()

Starter পুরো input-কে token-এ ভাগ করে। Token হলো space বা লাইন-ভাঙার মাঝখানের এক টুকরো text, আর প্রতিটা token একটা string। next() পরের token-টা যেমন আছে তেমনই দেয়, একটা string। nextInt() হলো Number(next()): একই token, সংখ্যায় convert করা।

মানে কোনো operator চলার আগেই, তুমি কোন reader call করছ সেটাই type ঠিক করে দেয়। যে value যোগ বা তুলনা করবে, সেটা পড়ো nextInt() দিয়ে। একটা শব্দ, একটা operator বা num:5-এর মতো typed token পড়ো next() দিয়ে। Text আর সংখ্যা দুটোই লাগলে, যেমন sum-and-join-এ লাগে, একবার next() দিয়ে পড়ো আর Number() দিয়ে convert করো।

দুই জায়গায় অন্য reader লাগে। bigint-sum 1018 পর্যন্ত পূর্ণসংখ্যা যোগ করে, সবচেয়ে বড় safe integer-এর অনেক উপরে, তাই প্রতিটা পড়ে BigInt(next()) দিয়ে। given-or-default আর missing-empty-zero ব্যবহার করে starter-এর lines variant। সেখানে token-এ ভাগ করার জায়গায় বসে const lines = input.split("\n");, তাই next() দেয় একটা পুরো লাইন, আর ফাঁকা লাইন আসে "" হয়ে।

নিচের ছবিটা একটা input-কে পুরো program-এর ভেতর দিয়ে অনুসরণ করে। উপরের সারিটা 5 2-এর ঠিক পথ; ড্যাশ দেওয়া সারিটা Bob-এর।

একটা input-এর পথ, stdin থেকে stdout একটা input, stdin থেকে stdout পর্যন্ত stdin token convert operator out.join stdout "5 2\n" একটা string "5" "2" দুটো string nextInt() 5 আর 2 5 + 2 7, একটা number String(7) "7" 7 Bob-এর পথ: শুধু next() "5" আর "2" এখনও string "5" + "2" জোড়া: "52" String("52") "52" 52 Judge পড়ে শুধু stdout-এর বাক্সটা। প্রতিটা number বের হয় String() দিয়ে: String(-0) হলো "0", আর String(1e21) হলো "1e+21"। 2^53 পেরোনো নিখুঁত পূর্ণসংখ্যার জন্য nextInt()-এর জায়গায় বসে BigInt(next())। টানা বাক্স: ঠিক পথ। ড্যাশ দেওয়া বাক্স: একই token, শুধু next() দিয়ে পড়া।

দুই সারিই একই দুটো token পড়ে, আর দুটোই শেষ হয় এমন একটা text-এ যেটা judge পড়ে। তফাত শুধু convert-এর বাক্সে, মানে পড়ার মুহূর্তেই একটা value-র type ঠিক হয়ে যায়।

Judge text মেলায়, তাই JavaScript যা print করে তা-ই print করো

Judge একটা hidden input দিয়ে তোমার পুরো program চালায়, আর program যা print করে সেটা লাইন ধরে ধরে মেলায়। লাইনের শেষে বাড়তি space থাকলে judge সেটা ধরে না। তোমার number-গুলো ও কখনো দেখে না, দেখে শুধু ওগুলো যে text হয়েছে সেটা। out-এ push করা প্রতিটা number text হয় out.join("\n") চলার সময়, আর সেই text হুবহু String() যা দেয় তা-ই।

এখানকার প্রতিটা statement-এ "JavaScript যেভাবে print করে" মানে এই text-টাই। বেশিরভাগ number তুমি যেমন ভাবো তেমনই print হয়। কয়েকটা অন্যরকম, আর judge দেখিয়ে দেওয়ার আগেই সেগুলো জেনে রাখা ভালো:

console.log(String(-0));
console.log(String(0.1 + 0.2));
console.log(String(7 / 2));
console.log(String(1 / 0), String(-1 / 0), String(0 / 0));
console.log(String(1e20), String(1e21));
console.log(String(0.000001), String(0.0000001));
console.log(String(9007199254740993));
0
0.30000000000000004
3.5
Infinity -Infinity NaN
100000000000000000000 1e+21
0.000001 1e-7
9007199254740992

লাইন 1: -0 একটা আসল সংখ্যা, কিন্তু String() ওটাকে print করে 0। লাইন 2 হলো Module 1-এ দেখা double-এর rounding, পুরোটা print করা। লাইন 4: JavaScript-এ শূন্য দিয়ে ভাগ করা error না, আর ফলাফলগুলো print হয় শব্দ হিসেবে।

লাইন 5: 1021 থেকে উপরে একটা number print হয় exponent রূপে, আর লাইন 6-এ 10-6-এর নিচেও তাই। লাইন 7: 9007199254740993 হলো 253-এর ওপারে, তাই print হওয়ার আগেই number-টার ভেতরে আছে 9007199254740992। তাই এই statement-গুলোর জন্য কখনো হাতে number format করবে না: push করে দাও, starter-এর out.join judge যেভাবে চায় সেভাবেই print করবে।

Hidden test যে কিনারাগুলো ধরে

প্রতিটা problem-এ 11 থেকে 16টা hidden test। এরা চলে সবচেয়ে ছোট input থেকে constraints যতটা বড় হতে দেয় ততটা পর্যন্ত, আর প্রতিটা test file 1 MiB-এর নিচে থাকে। এই দুইয়ের মাঝখানে বসে আছে এমন প্রতিটা value, যাকে এই module তোমাকে ভয় পেতে শিখিয়েছে। Table-টা ওদের নাম বলে দেয়, যাতে তুমি আগেই ওগুলো চালিয়ে দেখতে পারো।

ProblemAccessTestHidden test যা চালায়
sum-and-joinFree16-0 -0, শুরুতে বাড়তি শূন্য, 0.1 0.2, 253 - 1 যোগ 1, 21 আর 25 অঙ্কের token
clean-numbersFree120x1f আর -0x1f, 0b আর 0o রূপ, চারভাবে লেখা Infinity, 1e400, 1_000, বাংলা অঙ্ক, 30000টা token
calculatorPro111 / 0, 1 / -0, 0 / 0, -0 ফলাফল, 253 পেরোনো যোগফল, e+21 আর e-7 দিয়ে print হওয়া ফলাফল, 10000 লাইন
largest-of-threeFree12তিনটা সমান সংখ্যা, সব ঋণাত্মক, 0-এর পাশে -0, 2.50, শুরুতে বাড়তি শূন্য, এমন সংখ্যা যাদের text-এর ক্রম আর সংখ্যার ক্রম মেলে না, 10000 লাইন
given-or-defaultPro11পরপর কয়েকটা ফাঁকা লাইন, NULL, পরে একটা space সহ null, শুধু space-এর field, 0 আর false, বাংলা text, 10000টা field
messy-measurementsPro121e3m, 0x1f, -0kg, 1.2.3, একা একটা . বা -, Infinityx, 40000টা token
truthy-or-falsyPro11ষোলোটা নামই দুই ক্রমে, minus-zero আর zero-bigint, একই নাম বারবার, 40000টা নাম
three-equalitiesPro11বারোটা জোড়া দুই দিক থেকে, বিশটা value-র প্রতিটা জোড়া (400 লাইন), str:0x10 আর str:1e3, 20000 লাইন
missing-empty-zeroPro11ফাঁকা লাইন, 0.0, 0x0 আর -0, text হিসেবে NaN আর Null, 007, 1e21, 20000 লাইন
bigint-sumPro12n = 1, একা 9007199254740993, +5 আর -007, 1018-এর 40000টা value, মোট 0

ছোট কিনারাগুলো Playground-এ চালিয়ে দেখো। ওর stdin বাক্সে সর্বোচ্চ 10000টা অক্ষর ধরে, তাই সবচেয়ে বড় test-গুলো ওখানে আঁটে না। এই সীমাটা বাক্সের, judge-এর না। তাছাড়া একটা কিনারা নিয়ে নিজে লেখা একটা test বড় test-এর চেয়ে বেশি কথা বলে।

এই দশটা problem-এ যে রূপগুলো লাগে

const a = nextInt();              a number: Number(next())
const word = next();              a token, kept as text
const line = next();              lines variant: one whole line, "" when empty
String(x)                         x as JavaScript prints it; out.join does the same
Number.isNaN(x)                   true for NaN and for nothing else
parseFloat(t)                     the number at the start of t, or NaN
x ?? "default"                    the right side only when x is null or undefined
x == null                         true for null and undefined, nothing else
a > b ? a : b                     the larger of a and b
Object.is(x, y)                   like ===, but NaN is NaN and 0 is not -0
let sum = 0n; sum += BigInt(t);   an exact sum of integers
if (value) { ... }                runs when value is truthy
  • নিচের প্রতিটা starter এই track-এর নির্দিষ্ট starter। ওর লাইনগুলো যেমন আছে রাখো, আর নিজের code লেখো comment যেখানে বলে সেখানে।
  • প্রতিটা problem-এর জন্য একটা সাধারণ for loop আর if-ই যথেষ্ট। ওদের সাথে দেখা হয়েছে Module 1-এর lesson 05-এ, আর শেখাবে Module 4।
  • প্রতিটা উত্তরের জন্য output-এর একটা লাইন push করো। শব্দগুলো print হয় statement যেভাবে লেখে হুবহু সেভাবে, ছোট হাতের অক্ষরে।
Example 1: একই দুটো token, দুইভাবে তুলনা

Kenji-র scoreboard দুটো score পড়ে বলে, প্রথমটা ছোট কি না। ও দুটোই পড়ে next() দিয়ে আর তুলনা করে। ও কী পায় দেখো, পাশে সংখ্যা দিয়ে তুলনাটাও।

const input = require("fs").readFileSync(0, "utf8");
const tokens = input.split(/\s+/).filter(Boolean);
let at = 0;
const next = () => tokens[at++];
const nextInt = () => Number(next());
const out = [];

const a = next();
const b = next();

out.push(typeof a + " " + typeof b);
out.push(String(a < b));
out.push(String(Number(a) < Number(b)));

console.log(out.join("\n"));
string string
true
false

এই output input 10 9-এর জন্য। লাইন 1 দেখাচ্ছে, দুটো token-ই string। দুটো string মেলানো হয় অক্ষর ধরে ধরে, আর "1" আসে "9"-এর আগে, তাই "10" < "9" true। সংখ্যা হিসেবে 10 কিন্তু 9-এর চেয়ে ছোট না।

কোনো error নেই, program দিব্যি চলে। এজন্যই largest-of-three বলে nextInt() দিয়ে পড়তে: token তুলনা করা program অনেক test পাশ করে, আর ফেল করে ঠিক সেগুলোতে যেখানে দৈর্ঘ্য আলাদা।

Run in Compiler
Example 2: যে number-গুলো অপ্রত্যাশিতভাবে print হয়

Zara মিটারের দূরত্বকে কিলোমিটারে নেয়। Input হলো n, তারপর n-টা দূরত্ব। Output-এর প্রতিটা লাইন একটা দূরত্বকে 1000 দিয়ে ভাগ করা, JavaScript যেভাবে print করে সেভাবে।

const input = require("fs").readFileSync(0, "utf8");
const tokens = input.split(/\s+/).filter(Boolean);
let at = 0;
const next = () => tokens[at++];
const nextInt = () => Number(next());
const out = [];

const n = nextInt();

for (let i = 0; i < n; i++) {
  const metres = nextInt();
  out.push(String(metres / 1000));
}

console.log(out.join("\n"));
1.5
0
0.3
0.0001
5e-7
1e+21

এই output input 6 আর 1500 -0 300 0.1 0.0005 1e24-এর জন্য। -0-কে 1000 দিয়ে ভাগ করলে তখনও -0, আর ওটা print হয় 0। 0.0005 / 1000 হলো 10-6-এর নিচে, তাই print হয় 5e-7, আর 1021 print হয় 1e+21।

এখানে কিছুই ভুল না। যে judge String()-এর text চায়, সে ঠিক এই লাইনগুলোই পায়, calculator-ও তাই। যে program নিজে number format করে, ধরো toFixed দিয়ে, সে পাঁচ নম্বর লাইনে print করে 0.00 আর ফেল করে।

Run in Compiler
Example 3: Bob-এর রসিদ, আর statement যে লাইনটা চায়

Bob একটা রসিদ print করে। Input হলো n, তারপর n-টা লাইন, প্রতিটায় একটা জিনিসের নাম আর দাম। ও প্রতিটা জিনিস print করে, তারপর মোট দুইবার: JavaScript যেভাবে print করে সেভাবে, আর ক্রেতার জন্য দুই দশমিক ঘর পর্যন্ত।

const input = require("fs").readFileSync(0, "utf8");
const tokens = input.split(/\s+/).filter(Boolean);
let at = 0;
const next = () => tokens[at++];
const nextInt = () => Number(next());
const out = [];

const n = nextInt();
let total = 0;

for (let i = 0; i < n; i++) {
  const item = next();
  const price = nextInt();
  total = total + price;
  out.push(item + " " + String(price));
}
out.push("total " + String(total));
out.push("shown " + total.toFixed(2));

console.log(out.join("\n"));
pen 0.1
eraser 0.2
ruler 0.3
total 0.6000000000000001
shown 0.60

এই output input 3, তারপর pen 0.1, eraser 0.2 আর ruler 0.3-এর জন্য। প্রতিটা লাইন একটা শব্দ পড়ে next() দিয়ে আর একটা দাম nextInt() দিয়ে, দুই reader পাশাপাশি। মোটটা আবার সেই double-এর rounding, আর toFixed(2) ওটাকে দুই দশমিক ঘরের একটা string-এ লুকিয়ে ফেলে।

কোন লাইনটা ঠিক, সেটা ঠিক করে statement, পছন্দ না। এই set-এর প্রতিটা statement বলে "JavaScript যেভাবে print করে", তাই print করতে হবে total-এর লাইনটা। কোনো statement দুই দশমিক ঘর চাইলে সেটা বলে দিত, আর তখন toFixed(2) হতো ঠিক।

Run in Compiler

এটা কোথায় কাজে লাগে

  • Browser-এর URLSearchParams। ঠিকানায় q না থাকলে ওর get("q") দেয় null, আর ?q= থাকলে দেয় ""। এই দুটো আলাদা করাটাই missing-empty-zero-এর কাজ।
  • HTML-এর number input। একটা <input type="number"> নিজের value JavaScript-কে দেয় string হিসেবে, ঘরে অঙ্ক দেখালেও। ওর valueAsNumber property দেয় সংখ্যাটা, আর ঘর ফাঁকা থাকলে NaN।
  • Twitter-এর API, version 1.1। Tweet-এর id হলো 64-bit পূর্ণসংখ্যা, 253-এর ওপারে, তাই ওর JSON প্রতিটা id পাঠাত দুইবার: id হিসেবে, একটা number, আর id_str হিসেবে, একটা string। JavaScript code পড়ত id_str, কারণ number-টা ততক্ষণে round হয়ে গেছে। X API-র version 2 id পাঠায় শুধু string হিসেবে।
  • Stripe-এর payment API। প্রতিটা amount হলো মুদ্রার সবচেয়ে ছোট এককে একটা পূর্ণসংখ্যা, যেমন cent। 10.50 ডলারের charge যায় 1050 হিসেবে, তাই Example 3-এর 0.1 + 0.2 টাকা-পয়সাকে কখনো ছোঁয় না।

যে ভুলগুলো সবাই করে

১. সংখ্যা পড়া next() দিয়ে।

const input = require("fs").readFileSync(0, "utf8");
const tokens = input.split(/\s+/).filter(Boolean);
let at = 0;
const next = () => tokens[at++];
const nextInt = () => Number(next());
const out = [];

const a = next();
const b = next();
out.push(String(a + b));

console.log(out.join("\n"));
52

এটা input 5 2-এর output। কোনো error নেই, Playground-এর verdict Success, তাই টের পাবে শুধু judge-এর Wrong Answer দেখে। দুটো token-ই string, আর + string জোড়া লাগায়। এই ভুলটা তুমিও করবে, কারণ -, * আর / নিজেরাই convert করে নিয়ে ভুলটা ঢেকে রাখে। পড়ো nextInt() দিয়ে।

২. BigInt-এর যোগফল 0 থেকে শুরু করা।

const input = require("fs").readFileSync(0, "utf8");
const tokens = input.split(/\s+/).filter(Boolean);
let at = 0;
const next = () => tokens[at++];
const nextInt = () => Number(next());
const out = [];

const n = nextInt();
let sum = 0;

for (let i = 0; i < n; i++) {
  sum += BigInt(next());
}
out.push(String(sum));

console.log(out.join("\n"));
TypeError: Cannot mix BigInt and other types, use explicit conversions

Input এখানে 2 আর 1 2। Playground-এর verdict Runtime error, আর stdout-এ কিছুই পৌঁছায় না, কারণ শেষ লাইনের আগেই error throw হয়। 0 একটা number, BigInt(next()) একটা bigint, আর + এই দুটো মেশাতে রাজি না। যোগফল শুরু করো 0n থেকে।

৩. BigInt(nextInt())।

const input = require("fs").readFileSync(0, "utf8");
const tokens = input.split(/\s+/).filter(Boolean);
let at = 0;
const next = () => tokens[at++];
const nextInt = () => Number(next());
const out = [];

const n = nextInt();
let sum = 0n;

for (let i = 0; i < n; i++) {
  sum += BigInt(nextInt());
}
out.push(String(sum));

console.log(out.join("\n"));
9007199254740992

Input 1 আর 9007199254740993, আর উত্তর একটা কম। nextInt() আগে একটা number বানিয়েছে, আর number-টা ততক্ষণে round হয়ে 9007199254740992 হয়ে গেছে। তারপর BigInt() সেই round হওয়া value-টাই হুবহু কপি করেছে। BigInt-কে দাও text-টা: BigInt(next())।

৪. যেখানে ?? লাগত, সেখানে ||।

const answer = "";
const count = 0;

console.log("[" + (answer || "default") + "]");
console.log("[" + (answer ?? "default") + "]");
console.log(count || 10, count ?? 10);
[default]
[]
10 0

কোনো error নেই, শুধু ভুল value। || প্রতিটা falsy value বদলে দেয়, তাই ফাঁকা উত্তর আর 0 গোনা দুটোই হারিয়ে যায়। ?? বদলায় শুধু null আর undefined। তুমি ||-এর দিকে হাত বাড়াবে, কারণ পুরোনো code-এ ওটা সবখানে, ES2020-এ ?? ভাষায় আসার আগের সময় থেকে।

মাথা খাটাও

Zara এই program-কে input দেয় -0 -0। Program একই value দুইবার print করে, একবার console.log দিয়ে আর একবার out-এর ভেতর দিয়ে।

const input = require("fs").readFileSync(0, "utf8");
const tokens = input.split(/\s+/).filter(Boolean);
let at = 0;
const next = () => tokens[at++];
const nextInt = () => Number(next());
const out = [];

const a = nextInt();
const b = nextInt();

console.log(a + b);
out.push(a + b);

console.log(out.join("\n"));

ওর দুটো লাইন এক না। লাইন দুটো কী, আর কেন? Zara প্রথম console.log-টা মুছে দিলে judge কোনটা দেখত?

একটা number-এর console.log String()-এর ভেতর দিয়ে যায় না। console.log(-0) আর console.log(String(-0)) পাশাপাশি চালিয়ে দেখো।

Problem 1: sum-and-joinসহজFree

Bob next() দিয়ে দুটো সংখ্যা পড়ে যোগ করেছিল, আর 5 আর 2-এর জন্য পেয়েছিল 52। এখন ও দুটো উত্তরই পাশাপাশি দেখতে চায়, যোগফল আর জোড়া লাগানো text, যাতে আর কখনো গুলিয়ে না ফেলে। Token দুটো পড়ো starter-এর next() আর nextInt() দিয়ে।

Input. এক লাইনে দুটো token, a আর b, মাঝে একটা space। প্রতিটা token দশমিকে লেখা একটা সংখ্যা: শুরুতে একটা minus চিহ্ন থাকতেও পারে, তারপর এক বা একাধিক অঙ্ক, আর চাইলে একটা দশমিক বিন্দু আর তার পরে এক বা একাধিক অঙ্ক। শুরুতে বাড়তি শূন্যও থাকতে পারে।

Output. দুই লাইন। লাইন 1-এ a আর b-কে সংখ্যা হিসেবে যোগ করে পাওয়া যোগফল, JavaScript যেভাবে একটা number print করে সেভাবে: মানে ওটার জন্য String() যা দেয়। লাইন 2-এ token দুটো text হিসেবে জোড়া লাগানো, আগে a, ঠিক যেভাবে টাইপ করা ছিল।

Constraints. প্রতিটা token-এ 1 থেকে 25টা অক্ষর।

Sample. Input 5 2 দিলে দুই লাইনে 7 আর 52।

const input = require("fs").readFileSync(0, "utf8");
const tokens = input.split(/\s+/).filter(Boolean);
let at = 0;
const next = () => tokens[at++];
const nextInt = () => Number(next());
const out = [];

// your code: read with next() and nextInt(), push every line of output to out
// Line 1: a and b added as numbers. Line 2: a and b joined as text.

console.log(out.join("\n"));
Run in Compiler

Hint 1

প্রতিটা token আসে string হয়ে। Output-এর কোন লাইনে string-গুলো যেমন আছে তেমন লাগে, আর কোনটায় লাগে সংখ্যা?

Hint 2

প্রতিটা token একবারই next() দিয়ে পড়ো আর একটা const-এ রেখে দাও। লাইন 2 হলো দুটো string-এর a + b। লাইন 1 যোগ করার আগে দুটোকেই Number() দিয়ে convert করে।

Solution

const a = next() আর const b = next() দুটো string রেখে দেয়। Number(a) + Number(b) যোগ করে, আর a + b জোড়া লাগায়, কারণ একপাশে string থাকলেই + জোড়া লাগায়। যোগফলটা String() দিয়ে push করো, অথবা number-টাই push করো আর out.join-কে text বানাতে দাও: দুটোই একই অক্ষর দেয়।

nextInt() দিয়ে দুইবার পড়লে টাইপ করা text হারিয়ে যায়, তাই 007 3-এর জন্য লাইন 2 print করে 73, যেখানে চাই 0073। parseInt ভগ্নাংশ ফেলে দেয় আর -3.5 1.25-এর জন্য print করে -2, যেখানে ঠিক উত্তর -2.25। Hidden test আরও চালায় -0 -0, যার যোগফল print হয় 0 আর জোড়া print হয় -0-0, আর 25 অঙ্কের token, যাদের যোগফল print হয় 2e+25।

Problem 2: clean-numbersসহজFree

Zara একটা sensor log থেকে একগাদা token পেয়েছে, আর তার কয়েকটা আবর্জনা। ও জানতে চায় কোনগুলো পরিষ্কার সংখ্যা। একটা token পরিষ্কার, যদি Number(token) NaN না হয়। Input পড়ো starter-এর nextInt() আর next() দিয়ে।

Input. প্রথম লাইনে n। দ্বিতীয় লাইনে n-টা token, space দিয়ে আলাদা। কোনো token-এর ভেতরে space নেই।

Output. n-টা লাইন, প্রতিটা token-এর জন্য একটা, input-এর ক্রমে। পরিষ্কার token হলে print করো yes, একটা space, তারপর JavaScript সংখ্যাটা যেভাবে print করে সেভাবে: String(Number(token))। নইলে print করো no।

Constraints. 1 <= n <= 30000। প্রতিটা token-এ 1 থেকে 20টা অক্ষর।

Sample. Input 5 আর 12 3.50 abc 007 12px দিলে পাঁচ লাইনে yes 12, yes 3.5, no, yes 7 আর no।

const input = require("fs").readFileSync(0, "utf8");
const tokens = input.split(/\s+/).filter(Boolean);
let at = 0;
const next = () => tokens[at++];
const nextInt = () => Number(next());
const out = [];

// your code: read with next() and nextInt(), push every line of output to out
// Read n, then n tokens. Per token: "yes " and the number, or "no".

console.log(out.join("\n"));
Run in Compiler

Hint 1

Number() পুরো token পড়ে, নইলে দেয় NaN। 0x1f, Infinity আর 1e3-এর জন্য ও কী দেয়? আন্দাজ করার আগে চালিয়ে দেখো।

Hint 2

প্রতিটা token-এর জন্য Number(token) একবার হিসাব করে রেখে দাও। Number.isNaN দিয়ে check করো, তারপর push করো "yes " + String(value) বা "no"।

Solution

Check-টা হলো Number.isNaN(value), যেটা true শুধু NaN-এর জন্য। বাকি প্রতিটা value পরিষ্কার, Infinity-ও, কারণ statement শুধু NaN-এর কথা জিজ্ঞেস করে। তারপর String(value) 007-এর জন্য print করে 7, 0x1f-এর জন্য 31 আর 1e3-এর জন্য 1000।

এখানে parseFloat ভুল reader: ও 12px-কে বলে 12। Token-টাই ফিরিয়ে দিলে 007 আর 3.50 টাইপ করা অবস্থায় print হয়, আর sample সেটা ধরে ফেলে। Number.isFinite Infinity-কে না বলে, অথচ ওটা পরিষ্কার। Hidden test-এ আরও আছে -0x1f (0x-এর আগে চিহ্ন বসে না), 1_000 আর বাংলা অঙ্কের ১২, তিনটাই no।

Problem 3: calculatorমাঝারিPro

Alice ওর দোকানের জন্য একটা পকেট calculator বানাচ্ছে। ও প্রতি লাইনে টাইপ করে একটা সংখ্যা, একটা operator আর আরেকটা সংখ্যা, আর calculator ফলাফল print করে। Bob-এর প্রথম version 5 + 2-এর জন্য print করেছিল 52, তাই Alice এবার ঠিকঠাক চায়। Input পড়ো starter-এর nextInt() আর next() দিয়ে।

Input. প্রথম লাইনে n। তারপর n-টা লাইন, প্রতিটা a op b: একটা সংখ্যা, একটা space, একটা operator, একটা space আর একটা সংখ্যা। Operator হলো +, -, * আর /-এর যেকোনো একটা। প্রতিটা সংখ্যা দশমিকে লেখা: শুরুতে একটা minus চিহ্ন থাকতেও পারে, তারপর এক বা একাধিক অঙ্ক, আর চাইলে একটা দশমিক বিন্দু আর তার পরে এক বা একাধিক অঙ্ক। শুরুতে বাড়তি শূন্যও থাকতে পারে।

Output. n-টা লাইন। লাইন i-তে থাকবে লাইন i-এর a op b-এর ফলাফল, সংখ্যা হিসেবে হিসাব করা, আর JavaScript একটা number যেভাবে print করে সেভাবে print করা। শূন্য দিয়ে ভাগ করলে JavaScript যা দেয় তা-ই print হবে: Infinity, -Infinity বা NaN।

Constraints. 1 <= n <= 10000। a আর b-এর প্রতিটায় 1 থেকে 20টা অক্ষর।

Sample. Input 5, তারপর পাঁচ লাইনে 5 + 2, 7 - 10, 6 * 7, 7 / 2 আর 1 / 0 দিলে পাঁচ লাইনে 7, -3, 42, 3.5 আর Infinity।

const input = require("fs").readFileSync(0, "utf8");
const tokens = input.split(/\s+/).filter(Boolean);
let at = 0;
const next = () => tokens[at++];
const nextInt = () => Number(next());
const out = [];

// your code: read with next() and nextInt(), push every line of output to out
// Read n, then n lines of a, op and b. Per line: the result as JavaScript prints it.

console.log(out.join("\n"));
Run in Compiler

Hint 1

a আর b string থেকে গেলে চারটা operator-এর কোনগুলো তবু ঠিক উত্তর দিত, আর কোনটা দিত না?

Hint 2

a পড়ো nextInt() দিয়ে, operator next() দিয়ে আর b nextInt() দিয়ে। Operator দেখে if আর else if দিয়ে হিসাবটা বাছো, তারপর push করো String(result)।

Problem 4: largest-of-threeসহজFree

Maria দিনে তিনবার তাপমাত্রা লিখে রাখে, আর প্রতিদিনের সবচেয়ে বড়টা চায়। Kenji বলে, Math.max call করো, ঝামেলা শেষ। কিন্তু এই problem ternary operator-এর অনুশীলন, তাই নিয়ম একটাই: শুধু ? :। Input পড়ো starter-এর nextInt() দিয়ে। প্রতিটা সবচেয়ে বড় সংখ্যা বের করো ? : দিয়ে, Math.max আর if ছাড়া; judge শুধু তোমার output দেখে, তাই নিয়মটা মানার দায়িত্ব তোমার।

Input. প্রথম লাইনে t। তারপর t-টা লাইন, প্রতিটায় তিনটা সংখ্যা, space দিয়ে আলাদা। প্রতিটা সংখ্যা দশমিকে লেখা: শুরুতে একটা minus চিহ্ন থাকতেও পারে, তারপর এক বা একাধিক অঙ্ক, আর চাইলে একটা দশমিক বিন্দু আর তার পরে এক বা একাধিক অঙ্ক। শুরুতে বাড়তি শূন্যও থাকতে পারে।

Output. t-টা লাইন। লাইন i-তে input-এর লাইন i-এর তিনটা সংখ্যার মধ্যে সবচেয়ে বড়টা, JavaScript একটা number যেভাবে print করে সেভাবে।

Constraints. 1 <= t <= 10000। প্রতিটা সংখ্যায় 1 থেকে 20টা অক্ষর।

Sample. Input 3, তারপর 3 9 4, -5 -2 -9 আর 10 9 100 দিলে তিন লাইনে 9, -2 আর 100।

const input = require("fs").readFileSync(0, "utf8");
const tokens = input.split(/\s+/).filter(Boolean);
let at = 0;
const next = () => tokens[at++];
const nextInt = () => Number(next());
const out = [];

// your code: read with next() and nextInt(), push every line of output to out
// Read t, then t lines of three numbers. Per line: the largest, found with ? : only.

console.log(out.join("\n"));
Run in Compiler

Hint 1

String হিসেবে কোনটা বড়, "9" নাকি "100"? আর সংখ্যা হিসেবে? উত্তরটা উপরের Example 1-এ আছে।

Hint 2

তিনটাই পড়ো nextInt() দিয়ে। প্রথমে a > b ? a : b দিয়ে a আর b-এর বড়টা রেখে দাও। তারপর একইভাবে ওটাকে c-এর সাথে তুলনা করো।

Solution

দুটো ternary, প্রতিটা একটা করে প্রশ্নের উত্তর দেয়: const largerOfAB = a > b ? a : b;, তারপর largerOfAB > c ? largerOfAB : c। কোনো nesting লাগে না, আর প্রতিটা লাইন একটা বাক্যের মতো পড়া যায়। সংখ্যা হলে তুলনাটাও সংখ্যার, আর String() 007-কে print করে 7, 2.50-কে 2.5।

next() দিয়ে পড়লে তুলনা হয় text-এর, আর sample-এর তৃতীয় লাইনে print হয় 9। জেতা token-টা টাইপ করা অবস্থায় print করলে, যেখানে 7 চাই সেখানে আসে 007। তাড়াহুড়োয় লেখা nested ternary, যেমন a > b ? (a > c ? a : c) : (b > a ? b : c), 5 5 4-এর জন্য print করে 4, কারণ a আর b সমান হলে উত্তর গড়িয়ে যায় c-তে।

Problem 5: given-or-defaultমাঝারিPro

David-এর sign-up form প্রতিটা field পাঠায় text-এর এক লাইন হিসেবে। কেউ যে field পূরণ করেনি, সেটা আসে null বা undefined হয়ে, আর David ওটার জায়গায় দেখায় default শব্দটা। কিন্তু ফাঁকা উত্তরও একটা উত্তর, 0-ও তাই। এই problem starter-এর lines variant ব্যবহার করে: token-এ ভাগ করার জায়গায় বসে const lines = input.split("\n");, তাই next() দেয় পরের পুরো লাইনটা, ফাঁকা লাইনসহ। n পড়ো nextInt() দিয়ে।

Input. প্রথম লাইনে n। তারপর n-টা লাইন, প্রতিটায় একটা field। যে লাইন হুবহু null, সেটা মানে value null। যে লাইন হুবহু undefined, সেটা মানে undefined। বাকি যেকোনো লাইন, ফাঁকা লাইনও, নিজেই text।

Output. n-টা লাইন, প্রতিটা field-এর জন্য একটা: [, তারপর value ?? "default", তারপর ]। Bracket দুটো প্রতিটা space আর প্রতিটা ফাঁকা text চোখের সামনে রাখে।

Constraints. 1 <= n <= 10000। প্রতিটা field-এর লাইনে 0 থেকে 60টা অক্ষর, আর শেষেরটা কখনো ফাঁকা না। প্রতিটা লাইন শেষ হয় একটা newline দিয়ে।

Sample. Input 5, তারপর Alice, null, একটা ফাঁকা লাইন, 0 আর undefined দিলে পাঁচ লাইনে [Alice], [default], [], [0] আর [default]।

const input = require("fs").readFileSync(0, "utf8");
const lines = input.split("\n");
let at = 0;
const next = () => lines[at++];
const nextInt = () => Number(next());
const out = [];

// your code: read with next() and nextInt(), push every line of output to out
// Lines variant: next() returns the next whole line, empty lines included.
// Read n, then n fields. Per field: "[" + (value ?? "default") + "]".

console.log(out.join("\n"));
Run in Compiler

Hint 1

?? কোন দুটো value বদলায়? একটা ফাঁকা লাইন কি ওদের একটা? Text "0"?

Hint 2

প্রতিটা লাইনের জন্য শুরু করো let value = line; দিয়ে। লাইনটা হুবহু ওই শব্দ হলে তবেই value বানাও null বা undefined। তারপর push করো "[" + (value ?? "default") + "]"।

Problem 6: messy-measurementsমাঝারিPro

Amara একটা design file আর একটা দোকানের catalogue থেকে মাপ কপি করে, আর প্রতিটার গায়ে একক লেগে থাকে: 12px, 3.5kg। ওর দরকার শুধু প্রতিটা token-এর শুরুর সংখ্যাটা। Input পড়ো starter-এর nextInt() আর next() দিয়ে।

Input. প্রথম লাইনে n। দ্বিতীয় লাইনে n-টা token, space দিয়ে আলাদা। কোনো token-এর ভেতরে space নেই।

Output. n-টা লাইন, প্রতিটা token-এর জন্য একটা, input-এর ক্রমে। Print করো String(parseFloat(token)), আর parseFloat(token) NaN হলে print করো invalid শব্দটা।

Constraints. 1 <= n <= 40000। প্রতিটা token-এ 1 থেকে 20টা অক্ষর।

Sample. Input 5 আর 12px 3.5kg -4.5c px12 .5m দিলে পাঁচ লাইনে 12, 3.5, -4.5, invalid আর 0.5।

const input = require("fs").readFileSync(0, "utf8");
const tokens = input.split(/\s+/).filter(Boolean);
let at = 0;
const next = () => tokens[at++];
const nextInt = () => Number(next());
const out = [];

// your code: read with next() and nextInt(), push every line of output to out
// Read n, then n tokens. Per token: the number at its start, or "invalid".

console.log(out.join("\n"));
Run in Compiler

Hint 1

Number("12px") হলো NaN। কোন converter একটা text-এর শুরু থেকে সংখ্যা পড়ে আর বাকিটা উপেক্ষা করে?

Hint 2

parseFloat(token) একটা const-এ রেখে দাও। Number.isNaN হ্যাঁ বললে push করো "invalid", নইলে String(value)।

Problem 7: truthy-or-falsyমাঝারিPro

Maria বারবার জিজ্ঞেস করে, একটা ফাঁকা array if-এর ভেতরে true হিসেবে গোনা হয় কেন। Zara তাই ষোলোটা value-র একটা table বানায়, প্রতিটার একটা ছোট নাম দিয়ে। প্রতিটা নামের জন্য program বলে দেয়, if ওটার value-কে true হিসেবে ধরে (truthy), নাকি false হিসেবে (falsy)। Input পড়ো starter-এর nextInt() আর next() দিয়ে।

Input. প্রথম লাইনে n। তারপর n-টা লাইন, প্রতিটায় এই table-এর একটা নাম। প্রতিটা নাম মানে ওর পাশে লেখা JavaScript value-টা।

নামValueনামValue
falsefalsetruetrue
zero0minus-zero-0
zero-bigint0nempty-string""
space-string" "zero-string"0"
false-string"false"nullnull
undefinedundefinednanNaN
empty-array[]empty-object{}
infinityInfinityminus-one-1

Output. n-টা লাইন, প্রতিটা নামের জন্য একটা, input-এর ক্রমে: নামটা, একটা space, তারপর truthy বা falsy।

Constraints. 1 <= n <= 40000। প্রতিটা নাম table-এর ষোলোটার একটা, আর একই নাম বারবার আসতে পারে।

Sample. Input 5, তারপর পাঁচ লাইনে zero, empty-string, zero-string, empty-array আর nan দিলে আসে zero falsy, empty-string falsy, zero-string truthy, empty-array truthy আর nan falsy।

const input = require("fs").readFileSync(0, "utf8");
const tokens = input.split(/\s+/).filter(Boolean);
let at = 0;
const next = () => tokens[at++];
const nextInt = () => Number(next());
const out = [];

// your code: read with next() and nextInt(), push every line of output to out
// Read n, then n names. Per name: the name, a space, then truthy or falsy.

console.log(out.join("\n"));
Run in Compiler

Hint 1

প্রতিটা নামের value একটা JavaScript literal হিসেবে লেখো। ষোলোটার কয়টা falsy? একটা লাইন লেখার আগে গুনে ফেলো।

Hint 2

if আর else if-এর একটা শিকল দিয়ে নামটাকে ওর value বানাও, তারপর সিদ্ধান্ত নিতে দাও if (value)-কে। Falsy নামের নিজস্ব কোনো list রেখো না।

Problem 8: three-equalitiesকঠিনPro

Kenji-র code review বলে, "== কখনো লিখবে না"। Maria দেখতে চায় == আসলে কী করে, === আর Object.is-এর পাশাপাশি, যেকোনো দুটো value-র জন্য। Zara প্রতিটা value লেখে একটা typed token হিসেবে, যাতে program text থেকে value-টা আবার বানিয়ে নিতে পারে। Input পড়ো starter-এর nextInt() আর next() দিয়ে। token.slice(4) দেয় token-এর প্রথম চারটা অক্ষরের পরের অংশটুকু, যেমন num:-এর পরের text; slice শেখাবে Module 3।

Input. প্রথম লাইনে n। তারপর n-টা লাইন, প্রতিটায় দুটো token x আর y, মাঝে একটা space। একটা token হলো এগুলোর একটা:

  • num: আর তারপর একটা text: সংখ্যা Number(text), যেমন num:-0, num:NaN বা num:Infinity;
  • str: আর তারপর একটা text: string হিসেবে text-টাই, আর শুধু str: মানে ফাঁকা string "";
  • bool:true বা bool:false: boolean-টা;
  • null বা undefined: ওই value-টাই।

Output. n-টা লাইন। লাইন i-তে input-এর লাইন i-এর জোড়ার জন্য তিনটা শব্দ: x == y, x === y আর Object.is(x, y), প্রতিটা true বা false, মাঝে একটা করে space।

Constraints. 1 <= n <= 20000। প্রতিটা token-এ সর্বোচ্চ 25টা অক্ষর, আর কোনো space নেই। num:-এর পরের text কখনো ফাঁকা না।

Sample. Sample হলো lesson 04-এর chart-এর বারোটা জোড়া। Input 12, তারপর বারো লাইনে num:1 str:1, num:0 str:, num:0 str:0, str: str:0, null undefined, null num:0, undefined num:0, num:NaN num:NaN, num:0 num:-0, bool:true num:1, bool:true str:true আর bool:false str:0। উত্তর আসে: তিনবার true false false, false false false, true false false, দুইবার false false false, false false true, true true false, true false false, false false false আর true false false।

const input = require("fs").readFileSync(0, "utf8");
const tokens = input.split(/\s+/).filter(Boolean);
let at = 0;
const next = () => tokens[at++];
const nextInt = () => Number(next());
const out = [];

// your code: read with next() and nextInt(), push every line of output to out
// Read n, then n lines of two typed tokens such as num:1 and str:1.
// Per line: x == y, x === y and Object.is(x, y), separated by spaces.

console.log(out.join("\n"));
Run in Compiler

Hint 1

আগে প্রতিটা token থেকে আসল value বানাও, তুলনা পরে। num:-0 কী হয়? আর str:?

Hint 2

token.slice(0, 4) দেখো: num: আর str:-এর বেলায় value আসে token.slice(4) থেকে। বাকি চারটা token পুরো শব্দ। তারপর push করো String(x == y), String(x === y) আর String(Object.is(x, y)), মাঝে space দিয়ে।

Problem 9: missing-empty-zeroমাঝারিPro

Bob-এর form reader লেখে value || "missing", আর ওর report 0 পরিমাণের জন্যও missing বলে, ফাঁকা রেখে দেওয়া field-এর জন্যও। Amara তিনটা আলাদা ব্যাপারের জন্য তিনটা আলাদা শব্দ চায়: কিছুই আসেনি, একটা ফাঁকা উত্তর এসেছে, আর একটা শূন্য এসেছে। এই problem starter-এর lines variant ব্যবহার করে: token-এ ভাগ করার জায়গায় বসে const lines = input.split("\n");, তাই next() দেয় পরের পুরো লাইনটা, ফাঁকা লাইনসহ। n পড়ো nextInt() দিয়ে।

Input. প্রথম লাইনে n। তারপর n-টা লাইন। প্রতিটা লাইনকে একটা value-তে decode করো, এই ক্রমে। যে লাইন হুবহু null সেটা null, আর হুবহু undefined হলে undefined। ফাঁকা লাইন মানে ফাঁকা string ""। বাকি যেকোনো লাইন হলো Number(line), যদি সেটা NaN না হয়, নইলে লাইনের text-টাই।

Output. n-টা লাইন, প্রতিটা value-র জন্য একটা। value == null হলে print করো missing, value === "" হলে empty, আর value === 0 হলে zero। নইলে print করো value, একটা space আর String(value)।

Constraints. 1 <= n <= 20000। n-টা লাইনের প্রতিটায় 0 থেকে 20টা অক্ষর, কোনোটার শুরুতে বা শেষে space নেই, আর শেষ লাইনটা কখনো ফাঁকা না।

Sample. Input 7, তারপর null, 0, একটা ফাঁকা লাইন, 12, abc, undefined আর -0 দিলে সাত লাইনে missing, zero, empty, value 12, value abc, missing আর zero।

const input = require("fs").readFileSync(0, "utf8");
const lines = input.split("\n");
let at = 0;
const next = () => lines[at++];
const nextInt = () => Number(next());
const out = [];

// your code: read with next() and nextInt(), push every line of output to out
// Lines variant: next() returns the next whole line, empty lines included.
// Decode each line, then print missing, empty, zero or value and the value.

console.log(out.join("\n"));
Run in Compiler

Hint 1

Number("") কত? তাহলে decode-এর ধাপগুলো কোন ক্রমে চলতে হবে?

Hint 2

আগে হুবহু মিলিয়ে decode করো null, undefined আর ফাঁকা লাইন, তারপর চেষ্টা করো Number(line)। Print করো একটা value == null check দিয়ে, তারপর === "", তারপর === 0।

Problem 10: bigint-sumকঠিনPro

Zara-র game server প্রতিটা player-এর point রাখে পূর্ণসংখ্যা হিসেবে, একেকটা 1018 পর্যন্ত। Season-এর মোট হলো সবগুলোর যোগফল। সাধারণ number হিসেবে যোগ করলে মোটটা 253 পার হওয়ার পর শেষের অঙ্কগুলো হারায়, তাই Zara চায় একদম নিখুঁত যোগফল। n পড়ো starter-এর nextInt() দিয়ে, আর প্রতিটা পূর্ণসংখ্যা next() দিয়ে।

Input. প্রথম লাইনে n। দ্বিতীয় লাইনে n-টা পূর্ণসংখ্যা, space দিয়ে আলাদা। প্রতিটা দশমিকে লেখা, শুরুতে একটা + বা - চিহ্ন থাকতেও পারে, আর শুরুতে বাড়তি শূন্যও থাকতে পারে।

Output. এক লাইনে n-টা পূর্ণসংখ্যার নিখুঁত যোগফল, দশমিকে, ঋণাত্মক হলে সামনে একটা minus চিহ্ন।

Constraints. 1 <= n <= 40000। প্রতিটা পূর্ণসংখ্যা -1000000000000000000 থেকে 1000000000000000000-এর মধ্যে, মানে 1018।

Sample. Input 3 আর 9007199254740991 9007199254740991 1 দিলে 18014398509481983।

const input = require("fs").readFileSync(0, "utf8");
const tokens = input.split(/\s+/).filter(Boolean);
let at = 0;
const next = () => tokens[at++];
const nextInt = () => Number(next());
const out = [];

// your code: read with next() and nextInt(), push every line of output to out
// Read n, then n integers. Print their exact sum: BigInt, not Number.

console.log(out.join("\n"));
Run in Compiler

Hint 1

1018 হলো 253-এর অনেক উপরে। nextInt()-এর ভেতরে 9007199254740993-এর কী হয়?

Hint 2

যোগফল শুরু করো 0n থেকে, আর প্রতিটা token-এর জন্য যোগ করো BigInt(next())। Push করো String(sum)।

সচরাচর যে প্রশ্নগুলো আসে

  • আমার উত্তর 0.30000000000000004, আর আমি জানি এটা মানে 0.3। Judge নিজে round করে নেয় না কেন?

    Judge text মেলায়, আর তুমি কোন অঙ্কগুলো বোঝাতে চেয়েছ সেটা ও জানতে পারে না। কী print করতে হবে সেটা বলে statement, আর এখানে সে বলে "JavaScript যেভাবে print করে"। তাই প্রত্যাশিত লাইনে 17টা অঙ্কই আছে, আর 0.3 print করা হতো ভুল উত্তর।

  • largest-of-three-এ কি Math.max ব্যবহার করতে পারি?

    Judge শুধু তোমার output দেখে, তাই পাশ করে যেত। কিন্তু problem-টা আছেই ternary operator-এর অনুশীলনের জন্য, আর statement সেটাই চায়। আসল code-এ Kenji-র Math.max-ই ঠিক জিনিস; এখানে ওটা অনুশীলনটাই এড়িয়ে যায়।

  • দুটো problem-এ lines variant কেন লাগে? ফাঁকা token বাদ দিলেই তো হয়।

    সমস্যাটা ঠিক ওখানেই। Token-এ ভাগ করলে ফাঁকা লাইন হারিয়ে যায়, কারণ .filter(Boolean) প্রতিটা ফাঁকা string সরিয়ে দেয়। তখন একটা ফাঁকা field উধাও হয়, আর পরের প্রতিটা field এক ঘর উপরে উঠে আসে। Lines variant প্রতিটা লাইনকে, ফাঁকা হোক বা না হোক, একটা value হিসেবে রাখে।

  • নিরাপদ থাকতে সবখানে BigInt কেন ব্যবহার করি না?

    Bigint শুধু পূর্ণসংখ্যা রাখে: BigInt("3.5") throw করে SyntaxError: Cannot convert 3.5 to a BigInt। হিসাবে ওটা number-এর সাথে মেশে না, আর Math.max(1n, 2n) throw করে TypeError: Cannot convert a BigInt value to a number। যেখানে মোট 253 পার হতে পারে সেখানে ব্যবহার করো, আর কোথাও না।

  • আমার program sample পাশ করে। তাহলে hidden test কেন ফেল করে?

    Sample একটাই ছোট উদাহরণ, statement বোঝানোর জন্য বাছা। Hidden test-এ আরও থাকে -0, NaN, Infinity, ফাঁকা লাইন আর সবচেয়ে বড় মাপ। উপরের কিনারার table ওদের নাম বলে দেয়; submit করার আগে ছোটগুলো Playground-এ চালিয়ে দেখো।

মূল কথা

  • সংখ্যা পড়ো nextInt() দিয়ে, text next() দিয়ে, নিখুঁত বড় পূর্ণসংখ্যা BigInt(next()) দিয়ে, আর যে লাইন ফাঁকা হতে পারে সেটা lines variant দিয়ে।
  • Judge text মেলায়, আর প্রতিটা number বের হয় String() দিয়ে: -0 print হয় 0, আর 0.1 + 0.2 print হয় 0.30000000000000004।
  • কোনো operator ছোঁয়ার আগেই প্রতিটা value-র type ঠিক করে নাও: একপাশে string থাকলেই + জোড়া লাগায়।
  • ?? রেখে দেয় "" আর 0, == null ধরে null আর undefined, আর Object.is আলাদা করে NaN আর -0।
  • Sample-এর আগে কিনারাগুলো test করো: -0, NaN, Infinity, একটা ফাঁকা লাইন আর সবচেয়ে বড় safe integer।
  • আরও গভীরে: Interview Pack, output puzzle, প্রশ্ন আর bug gallery (Pro)।

এরপর আসছে module test: দশটা প্রশ্ন আর এই set-এর দুটো problem, calculator আর clean-numbers। তারপর cheat sheet পুরো module-কে এক পাতায় আনে, আর Module 3 খোলে string।

lesson ৭ শেষ

সব problem accepted হলেই lesson শেষ।

৩ টা free problem-এর মধ্যে ০ টা accepted

পরেরটা: Cheat sheet: এক পাতায় type, operator আর coercion

Problem: type আর coercion | Learn JavaScript | Progsity