Sain vinkin joulukalenterista ja ajattelin jakaa sen tännekin:
https://adventofcode.com/
Ideana on, että joka päivä tulee uudet tehtävät, jotka pitää ratkaista. Alussa on aika helppoja, mutta ilmeisesti nämä vaikeutuvat loppua kohden.
Kiitos vinkistä!
Näitä voikin hauskasti ratkoa JavaScriptilla selaimen konsolissa. Syöte on document.body.textContent, pilkkomisessa auttavat säännölliset lausekkeet.
Alkupään tehtävät ovat hauskoja eivätkä kovin vaikeita. Käyttämäni ohjelmointikielet sopivat myös erinomaisesti näiden tehtävien ratkaisuun.
Kolmostehtävän kakkososiokin voidaan PL/I:llä esittää muodossa:
dcl map(0:322, 0:30) char(1); dcl path1(0:322) defined(map(1sub, mod(1sub, 31))) char(1); dcl path2(0:322) defined(map(1sub, mod(1sub*3, 31))) char(1); dcl path3(0:322) defined(map(1sub, mod(1sub*5, 31))) char(1); dcl path4(0:322) defined(map(1sub, mod(1sub*7, 31))) char(1); dcl path5(0:161) defined(map(1sub*2, mod(1sub, 31))) char(1);
Myös tehtävä 5 näyttäisi soveltuvan PL/I:lle hyvin:
Esimerkin istuin id:n laskeminen:
dcl b bit(10); dcl i fixed bin(31); b = translate('FBFBBFFRLR', '0101', 'FBLR'); i = b; put skip list(i);
Enpä tiedä, miten moni täällä tekee tehtäviä, mutta halukkaat voivat liittyä sivustolla yksityiseen tuloslistaan koodilla 1142475-414cff12
. Tosin itse en ainakaan päivystä koneella tehtävien julkaisuhetkellä, joten välttämättä ei ropise pisteitä ratkaisunopeudesta.
Olen ajatellut myös Ohjelmointiputkaan tehtäviä, jotka voisivat olla vähän tämän tyyppisiä, että tuloksena olisi yksi luku. Täytyypä yrittää vaikka ensi vuonna toteuttaa tämä.
jalski kirjoitti:
Myös tehtävä 5 näyttäisi soveltuvan PL/I:lle hyvin
Toistaiseksi myös JavaScriptilla on ollut helppo edetä. Esimerkiksi tehtävä 6 ratkeaa näppärästi yhden rivin koodilla, johon sisältyy mm. sellaisia sanoja kuin map, filter, split, every, indexOf, join, length.
Metabolix kirjoitti:
Tosin itse en ainakaan päivystä koneella tehtävien julkaisuhetkellä, joten välttämättä ei ropise pisteitä ratkaisunopeudesta.
Itsellä sama, iltapäivällä kun tehtävän ratkaisee niin 0 pistettä taitaa ropsahtaa, mutta onhan noita mukava ratkoa.
Metabolix kirjoitti:
halukkaat voivat liittyä sivustolla yksityiseen tuloslistaan
Liitytty
Edit. myös c++:lla on helppo ratkoa tehtäviä
Toistaiseksi vasta 3 ratkaistu, kun hetki sitten niitä aloin ratkaisemaan, mutta myös Pythonilla menee kevyesti.
AtskaFin kirjoitti:
Edit. myös c++:lla on helppo ratkoa tehtäviä
Masokismin muoto tuokin! ;) Miksi muuten C++ näihin tehtäviin? Aika -ja muistinkäyttörajaa tehtävissähän ei ole...
Tehtävä 8:n ensimmäinen osio ratkesi elegantisti 8th:lla, antamalla 8th:n tulkata tehtävän op-koodeja suoraan. Millaiseen ratkaisuun C++:lla päädyit?
ns? ns: VM a:new "input8.txt" f:slurp ' a:push s:eachline constant memory var pc var accumulator : nop parsews drop 1 pc n:+! ; : acc parsews >n accumulator n:+! 1 pc n:+! ; : jmp parsews >n pc n:+! ; : interpret ns:VM only memory repeat pc @ a:@ extra@ false ?: not if true extra! eval else drop break then again drop null only ; ns : app:main VM:interpret VM:accumulator @ VM:pc @ "pc: %d, accumulator: %d\n" s:strfmt . bye ;
jalski kirjoitti:
Millaiseen ratkaisuun C++:lla päädyit?
Tämä sisältää ratkaisun myös b -tehtävään.
#include <iostream> #include <string> #include <vector> using namespace std; long long acc = 0; vector<pair<char, int>> boot_code; vector<int> visited; void reset() { for (int& i : visited) i = 0; acc = 0; } void readBootCode() { while (!cin.eof()) { string cmd; cin >> cmd; string val; cin >> val; boot_code.push_back( { cmd[0], stoi(val) } ); } } bool run() { reset(); int line = 0; while (!visited[line]) { if (line >= boot_code.size()) { return true; } visited[line] = 1; char cmd = boot_code[line].first; int val = boot_code[line].second; switch (cmd) { case 'j': line += val; break; case 'a': acc += val; case 'n': default: line++; break; } } return false; } void changeCmd(int line) { char& ref = boot_code[line].first; ref = ref == 'n' ? 'j' : 'n'; } void fixLoop() { for (int line = 0; line < (int)boot_code.size(); line++) { char cmd = boot_code[line].first; if (cmd == 'a') { continue; } changeCmd(line); if (run()) { break; } changeCmd(line); } } int main() { cout << "Choose part of task (A/B) "; string c; cin>>c; if (c != "A" && c != "B" && c != "a" && c != "b") { cout << "Wrong input"; return 0; } freopen("./inputs/08.txt", "r", stdin); readBootCode(); visited.resize(boot_code.size()); if (c == "B" || c == "b") { fixLoop(); } run(); cout << acc << "\n"; }
Jäin jumiin eilisen tehtävän jatko-osan suhteen. Ehkä en ymmärtänyt tehtävää oikein.
Day 9 kirjoitti:
you must find a contiguous set of at least two numbers in your list which sum to the invalid number from step 1
En löytänyt peräkkäisiä numeroita, jotka täyttäisivät em. ehdon. Eli tarvitseeko numeroiden olla peräkkäin? Ja jos ei, niin miten lähellä niiden pitää olla toisiaan? Kun valitsin vain numerot, joiden summa on haettu luku, niin ei mennyt läpi.
TapaniS: Kyllä listasta pitäisi löytyä yhtenäinen vähintään kahden luvun mittainen pätkä, jonka summa on oikea. Ilmeisesti syötteet generoidaan joka käyttäjälle erikseen, mutta omalla kohdallani ratkaisun pituus oli noin 20 lukua ja siitä kysytyt pienin ja suurin luku (ei ensimmäinen ja viimeinen) olivat kokoluokaltaan noin 100000. Alkeellinen ratkaisu on siis käydä läpi kaikki mahdolliset alku- ja loppuindeksit i–j ja laskea välien summat (nopeus O(n³)). Nopea ratkaisu taas etsii summaa vauhdissa ja käsittelee jokaista lukua enintään kaksi kertaa (nopeus O(n)), keksitkö myös sen? Kisakoodarin käsikirjasta löytyy vinkki lukuvälin summan laskemiseen.
Riviltä 618 löytyy luku 731031916, joka on hyväksytty ensimmäisen vaiheen ratkaisuksi. Tähän ei löydy alkeellista eikä nopeaa ratkaisua! ;(
----------
No nyt se löytyikin!
Jostain syystä Javan oheinen vertailu ei toiminut Long -tyypin luvuilla!
if (summa == target){ }
Eli varmaan olisi pitänyt tehdä jotenkin näin:
if (summa.longValue() == target.longValue()){ }
Eli välillä 503-519 on ratkaisu tähän.
TapaniS: Vika on siinä, että käytät Long-luokkaa (isolla) etkä long-perustietotyyppiä (pienellä). Vaikka arvo on sama, vertailussa on kaksi eri oliota, jolloin vertailun tulos ei ole toivottu. Helpoin ratkaisu on siis vaihtaa alkukirjain pieneksi. Ainoastaan joissain Javan tietorakenteissa on oltava sisältönä olioita, jolloin esimerkiksi HashSet<Long> on oikein, ja silloinkin pitää olla tarkkana tämän olio-ongelman ja tyyppien kanssa.
Metabolix kirjoitti:
Enpä tiedä, miten moni täällä tekee tehtäviä, mutta halukkaat voivat liittyä sivustolla yksityiseen tuloslistaan koodilla
1142475-414cff12
. Tosin itse en ainakaan päivystä koneella tehtävien julkaisuhetkellä, joten välttämättä ei ropise pisteitä ratkaisunopeudesta.
Nyt vasta tajusin, että tuossahan on putkan sisäinen tuloslista! Hieno homma!
Tämä alkaa olla jo hyvin pureskeltu, mutta minua jäi vaivaamaan, kun en ymmärtänyt viimeistä tehtävää. Voisikohan joku valaista, mitä tuo alla oleva lainaus tarkoittaa? Pitääkö numeroa 7 monistaa tai pitääkö "subject number" olla 7 numeron pituinen tai jotakin muuta? Ja mikä on tuo "subject number"?
Day 25 kirjoitti:
The card transforms the subject number of 7 according to the card's secret loop size. The result is called the card's public key.
---------------
Äh, no nyt tajusin! Eka osa meni läpi, mutta pitääköhän olla kaikki edelliset ratkaistuna, että toinen osa tulee valmiiksi? Nyt en pysty lähettämään vastausta tai edes löydä kysymystä, johon pitäisi vastata. :(
---------------
Haastetta tuntui loppua kohti tulevan mukavasti lisää. Ensi vuonna uudestaan!
Tuolta muuten löytyy vastaava kalenteri vuodesta 2015 alkaen: Kalenterit
TapaniS kirjoitti:
pitääköhän olla kaikki edelliset ratkaistuna, että [25. tehtävän] toinen osa tulee valmiiksi? Nyt en pysty lähettämään vastausta tai edes löydä kysymystä, johon pitäisi vastata. :(
En muista tarkemmin, mitä 25. tehtävän toisessa osassa luki ennen ”lähettämistä”, mutta siinä ei ollut tehtävää vaan tähden sai suunnilleen painamalla tyhjän lomakkeen ok-nappia. Nopeimmilla tämä on vienyt vain noin 4 sekuntia tuloslistan mukaan.
Aihe on jo aika vanha, joten et voi enää vastata siihen.