Rumah >hujung hadapan web >tutorial js >Histeria ahli sejarah

Histeria ahli sejarah

Mary-Kate Olsen
Mary-Kate Olsenasal
2024-12-08 10:38:13769semak imbas

Historian Hysteria

Kedatangan Kod 2024 Hari 1

Bahagian 1

Bola lisut untuk memulakan tahun dengan senyuman

Menyelesaikan perkara ini nampaknya mudah:

Parse the input into two equal lists of numbers
Sort each list in ascending order
Compare both values at each index
Determine the absolute value after calculating the difference
Increment a tally by the absolute value

Langkah 1: buat dua senarai nombor

Pertama, saya akan membuat senarai senarai 2 item dengan setiap item adalah nombor:

input.split('\n').split(' ').map(Number)

Kemudian, saya akan mengekstrak item ke dalam senarai berasingan berdasarkan indeksnya:

let [list1, list2] = [
  input.map((_,i) => i == 0),
  input.map((_,i) => i == 1)
]
Menjalankannya dan membetulkan kesilapan saya

Kesilapan pertama: perpecahan rantai.
Saya tidak boleh memanggil split pada tatasusunan.
Saya perlu berpecah dalam kaedah lelaran, seperti peta:

input.split("\n").map(...);

Kesilapan kedua: ruang tidak mencukupi.
Input mengandungi beberapa ruang antara setiap nombor, bukan satu:

input.split("\n").map((el) => el.split("   ").map(Number));

Kesilapan ketiga: terlalu memikirkan akses senarai.

Kod saya bertindak seolah-olah setiap senarai bersarang ialah satu elemen dan mengembalikan nilai boolean berdasarkan sama ada elemen itu pertama atau kedua dalam senarai.

Apa???!!!

Kod ini mengenali setiap senarai dan menyimpan item pertama atau kedua:

let [list1, list2] = [
  input.map(list => list[0]),
  input.map(list => list[1]),
];

Malangnya, algoritma saya kini menjana dua senarai nombor!

Wah, saya agak berkarat kerana tidak melakukan ini selama sepuluh bulan.

Isih setiap senarai dalam tertib menaik

Ini sepatutnya pendek dan manis.

Malah, saya hanya akan menambah kod terus di atas:

let [list1, list2] = [
  input.map(list => list[0]).sort((a,b) => a - b),
  input.map(list => list[1]).sort((a,b) => a - b),
];

Berfungsi seperti azimat pada input contoh:

[ 1, 2, 3, 3, 3, 4 ]
[ 3, 3, 3, 4, 5, 9 ]

Tiga langkah yang lain, semuanya serentak!

let answer = 0;
for (let i = 0; i < list1.length; i++) {
  answer += Math.abs(list1[i] - list2[i]);
}

Ia berfungsi pada contoh: 11

Adakah ia berfungsi pada input teka-teki saya?

Memang betul!

Woohoo! Satu bintang emas!

Bahagian 2

Pusingan yang menyeronokkan untuk menguji masa larian

Arahan itu akan membuatkan saya percaya:

For each number in list 1
  For each number in list 2
    If there's a match
      Increment a tally by 1

Ini bermakna senarai 2 akan disemak senarai 2 panjang kali senarai 1 panjang...kali.

1000 item dalam setiap satu: 1 juta cek

Itu tidak buruk. Tetapi itu nampaknya tidak perlu.

Apa yang saya pentingkan ialah kiraan setiap nombor dalam senarai 2.

Jadi, saya boleh menyemak kesemua 1000 nombor sekali, dan membina peta nombor mengikut kiraan mereka. Kemudian, semak senarai itu 1000 kali.

2000 < 1 juta

Saya lebih suka pendekatan ini. Kepada kod!

Membina peta nombor dan kiraan

Senarai contoh kelihatan seperti:

4, 3, 5, 3, 9, 3

Jadi saya mahukan objek yang kelihatan seperti:

{
  4: 1,
  3: 3,
  5: 1,
  9: 1
}

Dengan senarai2 saya daripada algoritma Bahagian 1 saya, saya perlu melakukan pengurangan untuk membina objek ini:

let counts = list2.reduce((obj, num) => {
  if (!(num in obj)) {
    obj[num] = 1
  } else {
    obj[num] += 1
  }
  return obj
}, {})

Saya terkejut, coretan itu berfungsi seperti yang diharapkan!

Saya fikir saya terlupa sintaks yang betul untuk num dalam obj, tetapi itu sahaja!

Satu carian mudah untuk setiap item senarai

Satu lagi pengurangan dengan syarat menyemak kewujudan dan nilai yang dikaitkan dengan nombor:

Parse the input into two equal lists of numbers
Sort each list in ascending order
Compare both values at each index
Determine the absolute value after calculating the difference
Increment a tally by the absolute value

Menyahpepijat selama-lamanya kerana, saya tidak percaya

Saya terus melihat markah yang salah.

Saya terus tertanya-tanya kenapa.

Saya terus menambah pernyataan console.log() dengan lebih banyak nilai untuk dicetak.

Saya terus melihat nilai yang saya tidak jangkakan.

Kemudian, saya melihatnya.

Saya membandingkan dengan list2 dan bukan objek kiraan tersuai saya!

Pukulan hebat kepada ego. Tetapi apa yang saya perlukan pada Hari 1.

Ini kod berfungsi:

input.split('\n').split(' ').map(Number)

Itu menjana jawapan yang betul untuk input contoh.

Semoga ia melakukan perkara yang sama untuk input teka-teki saya.

Dan semoga ia berjalan sepantas kilat!

Memang betul!

Yeeeehawwww!!!

Dua bintang emas untuk memulakan sesuatu.

Bersama-sama dengan beberapa kesilapan pemula yang membuatkan saya berasa yakin.

Ini semua sebab saya suka teka-teki ini.

Seterusnya juga Hari 2!

Atas ialah kandungan terperinci Histeria ahli sejarah. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn