Skąd się tu wziąłeś?

9

INTERCAL to wspaniały język, ale nie zawsze łatwo jest zrozumieć kod innych ludzi. Jest tak szczególnie w przypadku, gdy używają instrukcji COME FROM.

INTERCAL TO SZALEŃSTWO

Definicja wyzwania

  1. Napisz program lub funkcję, która pobierze kod źródłowy programu INTERCAL jako strumień tekstu / danych. Jeśli piszesz funkcję, zalecane jest także zapewnienie programu do wywołania funkcji, ale nie będzie się ona liczyła do twojego wyniku.
  2. Wyjściem funkcji będzie strumień tekstowy / danych skoków wykonywanych przez program, zgodnie z następującymi instrukcjami. Wynik nie musi być drukowany, ale musi to być pojedynczy tekst, a nie tablica ciągów znaków (na przykład).
  3. Każdy wiersz wyniku będzie składał się z instrukcji, która będzie COME FROM, i numeru linii jej instrukcji COME FROM, oddzielonych znakiem ->. Przykład:

    (310)   DO .4 <- .3 -> 55
    
  4. Możesz przyciąć te wiersze kodu źródłowego, ale nie jest to konieczne.

  5. Przypadki testowe będą składały się wyłącznie z niezliczonych etykiet (tj. Etykiet całkowitych).
  6. Dane wyjściowe muszą być posortowane według kolejności kodu źródłowego instrukcji, które będą COME FROM, a nie według ich etykiety, ani kolejności instrukcji COME FROM ani ich etykiet.
  7. Możliwe jest, aby wiele instrukcji pochodziło z tej samej etykiety. W takich przypadkach numery linii COME FROM muszą być posortowane i oddzielone przecinkami.
  8. Możliwe jest, że instrukcja przyjdzie sama.
  9. Instrukcja COME FROM może być poprzedzona instrukcją NOT. W takich przypadkach numer linii musi być owinięty w nawiasy kwadratowe.
  10. Słowa COME FROM mogą pojawić się w komentarzu i muszą zostać zignorowane. Nie musisz w pełni analizować pliku: jeśli po nich następuje etykieta (liczba w nawiasach), możesz założyć, że jest to prawdziwa instrukcja.

Punktacja

Uczestnicy będą oceniani według długości znaków ich programu lub funkcji.

Przypadki testowe

Wszystkie te przypadki testowe pochodzą z repozytorium calithmetcalf / intercal Github . Chociaż każda przydatna aplikacja bezpiecznie zaakceptuje dowolne dane wejściowe, do celów tego wyzwania potrzebujesz tylko tych pięciu przypadków testowych.

rot13.i

(10) PLEASE DON'T GIVE UP -> 87
(33) DON'T GIVE UP -> 92

primes.i

(15)    DO (13) NEXT -> 26
(16)    DO .12 <- .1 -> 6
(23)    DO (21) NEXT -> 3

unlambda.i

(7202)  DO RETRIEVE .203+,202 -> 75
(4202)  DO ,202SUB.201.202#7 <- ,201SUB.201.202#7 -> 108
(6202)  DO ,201SUB.201.202#7 <- ,202SUB.201.202#7 -> 117
(4203)  DO READ OUT ,201SUB.201.202#7 -> 133
(4302)  DO .302 <- .2 -> 181
(5410)  DO ,400SUB#124 <- #4 $ #17 -> 293
(3410)  PLEASE (4410) NEXT -> 288
(5402)  DO (412) NEXT -> 328
(4412)  PLEASE (3412) NEXT -> 334
(3423)  DO FORGET #2 -> 375
(4404)  DO RETRIEVE .311+.312 -> 411
(5404)  PLEASE DO (414) NEXT -> 430
(4434)  DO FORGET #1 -> 441
(3454)  DO (103) NEXT -> 451
(5502)  DO .512 <- .312 -> 520
(8503)  PLEASE RETRIEVE .311+.312 -> 621
(7503)  DO (302) NEXT -> 515
(3622)  DO (302) NEXT -> 514
(603)   PLEASE FORGET #2 -> 622

pass.i

(10)    DO  NOTHING -> 5, 11
(20)    PLEASE  (100) NEXT -> 6
(30)    PLEASE  (200) NEXT -> 12
(103)   DO  (104) NEXT -> 27
(104)   DO  (105) NEXT -> 19
(1) DO  (2) NEXT -> 36
(2) DO  (105) NEXT -> 194
(202)   DO NOT  .2 <- #2 AGAIN -> [196]
(203)   DO  (204) NEXT -> 167
(204)   DO  (205) NEXT -> 159

kontynuacja. i

(8201)  DO NOTHING -> 165, 271
(8202)  PLEASE NOTE Fork threads, one dormant, one alive -> 53, 58
(8211)  DO COME FROM (8211) -> 60
(8216)  DO NOTHING -> 71
(8215)  DO NOTHING -> 68
(8217)  DO COME FROM (8217) AGAIN -> 118
(8299)  DO COME FROM (8299) AGAIN -> 141
(8274)  DO (8273) NEXT ONCE -> 158
(8259)  PLEASE DO NOTHING -> 166
(8276)  DO COME FROM (8276) AGAIN -> 199
(8278)  PLEASE DO COME FROM (8278) AGAIN -> 237
ciekawy
źródło
2
Dziwię się, że nikt jeszcze nie wspomniał o Cotton Eyed Joe :-).
mınxomaτ
22
INTERCAL is a wonderful languageoddany za obraźliwy język.
Fatalize
Czy na pewno chcesz oceniać według długości znaków? Wyzwania są tutaj zwykle oceniane według długości bajtów.
Fatalize
@Fatalize Myślałem o tym na dwa sposoby. Wspólne zalety punktacji postaci, takie jak kodowanie dużych liczb jako znaków Unicode, prawdopodobnie nie będą przydatne, ale pomyślałem, że jeśli ktoś może skorzystać z punktacji, chciałbym zobaczyć, co da się zrobić.
curiousdannii
Czy możemy założyć, że etykieta znajduje się na początku wiersza? Taki, który ^(\d+)chwyta etykietę?
orlp

Odpowiedzi:

2

JavaScript, 232 bajty

function c(d){for(var l,o,f,c,p=/^.(\d+).+?$/gm,a=/(T\s+)?C.{7}M .(\d+)/g,r='';l=p.exec(d);)for(f=0;o=a.exec(d);)o[2]==l[1]&&(c=d.slice(0,o.index).split('\n').length,r+=f++?', ':'\n'+l[0]+' -> ',r+=o[1]?'['+c+']':c);return r.trim()}

Do połączenia z

var data = require( 'fs' ).readFileSync( process.argv[2] ).toString();
console.log( c( data ) );

Wyjaśnienie

function c(d){
    for(
        // Initialise variables
        var l,o,f,c,p=/^.(\d+).+?$/gm,a=/(T\s+)?C.{7}M .(\d+)/g,r='';
        // Find lines beginning with a label
        l=p.exec(d);)
            for(
                // Reset a have-we-output-this-line flag
                f=0;
                // Find CALL FROM statements
                o=a.exec(d);)
                    // Filter to CALL FROM statements which have the current line
                    o[2]==l[1]&&(
                        // Calculate the line number of this CALL FROM statement
                        c=d.slice(0,o.index).split('\n').length,
                        // Concat the output for this line
                        r+=f++?', ':'\n'+l[0]+' -> ',r+=o[1]?'['+c+']':c);
    // Trim an initial new line
    return r.trim()}
ciekawy
źródło
1
Największym wzdęciem jest tutaj obliczenie numeru linii, ale jako autor wyzwania pomyślałem, że zostawię to jako łatwą próbę pokonania.
curiousdannii