De onde você veio?

9

INTERCAL é uma linguagem maravilhosa, mas nem sempre é fácil entender o código de outras pessoas. Esse é particularmente o caso se eles usarem a instrução COME FROM.

INTERCAL É LOUCURA

Definição de desafio

  1. Escreva um programa ou função que aceite o código fonte de um programa INTERCAL como um fluxo de texto / dados. Se você escrever uma função, é recomendável que você também forneça um programa para chamá-la, mas isso não será contabilizado para sua pontuação.
  2. A saída da função será um fluxo de texto / dados dos saltos efetuados pelo programa, de acordo com as seguintes instruções. A saída não precisa ser impressa, mas precisa ser um texto único, não uma matriz de seqüências de caracteres (por exemplo).
  3. Cada linha de saída consistirá na instrução COME FROM e no número da linha de sua instrução COME FROM, separados por a ->. Um exemplo:

    (310)   DO .4 <- .3 -> 55
    
  4. Você pode aparar essas linhas de código fonte, mas não é necessário.

  5. Os casos de teste consistirão apenas em rótulos não computados (ou seja, rótulos inteiros).
  6. A saída deve ser classificada pela ordem do código-fonte das instruções que serão COME FROM, não pelo rótulo, nem pela ordem das instruções COME FROM ou por seus rótulos.
  7. É possível que várias instruções venham do mesmo rótulo. Nesses casos, os números de linha COME FROM devem ser classificados e separados por vírgulas.
  8. É possível que uma declaração venha de si mesma.
  9. Uma instrução COME FROM pode ser prefixada com uma instrução NOT. Nesses casos, o número da linha deve estar entre colchetes.
  10. As palavras COME DE podem aparecer em um comentário e devem ser ignoradas. Você não precisa analisar completamente o arquivo: se eles forem seguidos por um rótulo (um número entre parênteses), poderá assumir que é uma declaração real.

Pontuação

Os participantes serão pontuados pelo tamanho do caractere de seu programa ou função.

Casos de teste

Todos esses casos de teste são provenientes do repositório calvinmetcalf / intercal do Github . Embora qualquer aplicativo útil aceite com segurança qualquer entrada, para os fins deste desafio, você só precisa considerar esses cinco casos de teste.

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

continuation.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
curiousdannii
fonte
2
Me surpreende que ninguém tenha feito uma referência ao Joe de Olhos de Algodão ainda :-).
mınxomaτ
22
INTERCAL is a wonderful languagevoto negativo para linguagem ofensiva.
Fatalizar
Tem certeza de que não deseja marcar pelo tamanho dos caracteres? Os desafios geralmente são pontuados pelo tamanho dos bytes aqui.
Fatalize 14/09/15
@Fatalize eu pensei sobre isso nos dois sentidos. As vantagens comuns da pontuação de caracteres, como codificar grandes números como caracteres unicode, provavelmente não serão úteis, mas pensei que se alguém puder tirar proveito da pontuação, eu estaria interessado em ver o que eles podem fazer.
Curiousdannii
Podemos assumir que o rótulo está no início de uma linha? Tal que ^(\d+)agarra o rótulo?
orlp

Respostas:

2

JavaScript, 232 bytes

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()}

Para ser chamado com

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

Explicação

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()}
curiousdannii
fonte
11
O maior inchaço aqui é calcular o número da linha, mas como autor do desafio, pensei em deixá-lo como uma tentativa fácil de tentar vencer.
Curiousdannii