Il sentiero nel bosco


9

Dopo il tuo disastroso giro in canoa , sei finito per cadere da una cascata alla fine delle rapide del fiume. La tua canoa è esplosa, ma sei riuscito a sopravvivere all'esplosione. Tuttavia, il tuo viaggio fluviale è andato completamente fuori dalla mappa: ora ti sei ritrovato perso nel mezzo di una foresta. Fortunatamente, hai ancora le tue capacità di programmazione, quindi decidi di scolpire un programma sul lato di un albero per aiutarti a trovare la strada attraverso la foresta. Tuttavia, non c'è molta superficie sull'albero, quindi è necessario rendere il programma il più breve possibile.

La foresta può essere descritto come nda n( n > 5) quadrato di caratteri, che consisterà solamente delle lettere minuscole a-z. Una foresta di esempio:

anehcienwlndm
baneiryeivown
bnabncmxlriru
anhahirrnrauc
riwuafuvocvnc
riwnbaueibnxz
hyirorairener
ruwiiwuauawoe
qnnvcizdaiehr
iefyioeorauvi
quoeuroenraib
cuivoaisdfuae
efoiebnxmcsua

Forse avrai notato che in questa foresta c'è una linea diagonale di apersonaggi che la attraversa dall'angolo in alto a sinistra all'angolo in basso a destra. Questo è un "percorso" attraverso la foresta che ti porterà da qualche parte se lo segui. Il tuo compito è scrivere un programma che troverà il percorso singolare. Descriverò più specificamente ciò che connota un "percorso" in questa sfida.

Un "percorso", in questa sfida, è definito come una linea simile a quella che potrebbe essere stata generata con un algoritmo di Bresenham , ma con i requisiti aggiunti che:

  • La riga deve contenere almeno 6 caratteri
  • Ogni gruppo collineare (completamente adiacente) di caratteri nella riga deve avere la stessa lunghezza .
  • Inizierà da un lato della foresta e finirà dal lato opposto (vedi il mio commento qui per l'elaborazione)

Per spiegare più chiaramente il secondo requisito, considerare la seguente riga:

aaa
   aaa
      aaa
         aaa
            aaa

Questa linea è composta da "segmenti" collineari di personaggi, ognuno dei quali è lungo esattamente tre caratteri. Si qualifica come un percorso. Ora considera questa riga:

a
 aa
   a
    aa
      a
       aa

Questa linea è composta da "segmenti" collineari che non hanno esattamente la stessa lunghezza di caratteri (alcuni di essi sono lunghi 1 carattere e alcuni sono 2). Pertanto, questo non si qualifica come un percorso.

Il tuo programma, data una mappa della foresta, identifica i personaggi usati nel percorso. L'input è qualunque cosa sia conveniente (es. Argomento della riga di comando, STDIN prompt(), ecc.). Non può essere pre-inizializzato in una variabile. La prima parte dell'input è un singolo intero che nrappresenta la dimensione della foresta (la foresta è sempre un quadrato). Dopo quello è uno spazio e quindi l'intera foresta come una singola stringa. Ad esempio, la foresta di esempio verrebbe presentata, come input, in questo modo:

13  anehcienwlndmbaneiryeivownbnabncmxlriruanhahirrnraucriwuafuvocvncriwnbaueibnxzhyirorairenerruwiiwuauawoeqnnvcizdaiehriefyioeorauviquoeuroenraibcuivoaisdfuaeefoiebnxmcsua

L'output per questo sarebbe:

a

perché il percorso è formato usando la lettera a. Ci sarà solo un percorso nella foresta. Questo è il golf del codice, quindi vince il numero più basso di caratteri. Se hai domande, chiedi nei commenti.


E se ci sono più percorsi?
Eric Tressler,

@EricTressler Ci sarà un solo percorso in ogni foresta. Modificherò la specifica per riflettere quella.
assenzio

La lettera del percorso potrebbe essere utilizzata da qualche altra parte in cui non appartiene al percorso?
Martin Ender,

La foresta di esempio lo contiene probabilmente. La prima a su questa riga nella foresta di esempio non fa parte del percorso anhahirrnrauc
Spade,

@ MartinBüttner Sì. Ma non saranno in alcun modo due percorsi creati dalla stessa lettera.
assenzio

Risposte:


3

APL (Dyalog 14) (70)

⎕ML←3⋄Z/⍨1=≢¨Z←∪¨(↓⍉F),(↓F),{(⍳≢⍵)⌷¨↓⍵}¨(⊂F),⊂⌽F←⊃{⍵⍴⍨2/⍎⍺}/I⊂⍨' '≠I←⍞

Spiegazione:

  • ⎕ML←3: impostato MLsu 3, il significato ha il suo significato APL2.
  • I←⍞: legge una riga dalla tastiera e la memorizza in I
  • I⊂⍨' '≠I: diviso Isugli spazi
  • {... }/: applica questa funzione alle due stringhe risultanti:
    • 2/⍎⍺: valuta l'argomento sinistro e replicalo due volte, dando la dimensione della matrice
    • ⍵⍴⍨: formatta l'argomento giusto usando quella dimensione
  • F←⊃: decomprimilo e memorizzalo in F.
  • {(⍳≢⍵)⌷¨↓⍵}¨(⊂F),⊂⌽F: ottieni le diagonali: da ogni riga in entrambi Fe ⌽F(con mirroring verticale F), ottieni il valore nella colonna X, dove X è il suo numero di riga
  • (↓⍉F),(↓F),: ottiene le righe e le colonne di F
  • Z←∪¨: trova i valori univoci su ogni riga, colonna e diagonale e memorizzali in Z.

Poiché la "foresta" è rettangolare, se esiste un percorso valido significa che uno di questi sarà costituito da un solo carattere, che è il carattere del percorso, quindi:

  • Z/⍨1=≢¨Z: prendi quei subarrays Zche hanno solo un elemento.

Questo mostrerà i caratteri per tutti i percorsi validi, ma poiché dovrebbe essercene solo uno che non ha importanza.


4

Lua - 506 380 - byte

Mi sentivo un po 'male per il fatto che non avessi ricevuto alcuna presentazione per la tua sfida ben ponderata, quindi l'ho buttato insieme. È stato divertente dedurre quali proprietà minime distinguibili il percorso deve avere dalle informazioni fornite. Spero di aver capito bene ... E di averlo correttamente implementato.

a=io.read"*l"n=a:match("%d+")+0 m=a:match"[a-z]+"o=""for i=1,n do for k=1,n^2,n do o=o..m:sub(i+k-1,i+k-1)end end q={m,o}for g=1,n^2 do for u=1,2 do l=q[u]:sub(g,g)for r=1,n do i=1 t=0 e=0 while i do s,e=q[u]:find(l:rep(r),e+1)if s then x=s-(e-s)-i-1 print(s,i,r,n,r)if x==n or x==n-2 or t==0 then t=t+1 i=s end else i=nil end end if t*r==n then print(l)os.exit()end end end end

Può essere testato con:

lua divisorPath.lua "input"

Se appare uno sfidante selvaggio, cercherò di golf il mio codice per quello che vale.

Aggiornamento : golf in onore di coloro che si alzeranno sopra di noi. Mentre ero lì ho dovuto correggere il mio codice sul percorso riconosciuto che andava da destra a sinistra. Ops.


3

MATLAB - 270 caratteri

Di seguito viene definita una funzione xche accetta una stringa della foresta come argomento e restituisce il carattere che rappresenta il "percorso" valido attraverso la foresta in base alle regole indicate.

function F=x(s),A=sscanf(s,'%d%s');n=A(1);A=reshape(A(2:end),n,n);for c=A(:)',B=A==c;for i=1:n,if~mod(n,i),C=[kron(eye(i),ones(n/i,1)),zeros(n,n-i)];for j=0:n-i,f=@(B)sum(sum(B&circshift(C,[0,j]))==n;D=fliplr(B);if f(B)|f(B')|f(D)|f(D'),F=char(c);end;end;end;end;end;end

La versione non ridotta è

function F = x(s)
    A = sscanf( s, '%d %s' );
    n = A(1);
    A = reshape( A(2:end), n,n );
    for c = A(:)'
        B = A==c;
        for i = 1:n
            if ~mod( n, i )
                C = [kron( eye(i), ones( n/i,1 ) ), zeros( n,n-i )];
                for j = 0:n-i
                    f = @(B) sum(sum( B & circshift( C, [0 j] ))) == n;
                    D = fliplr(B);
                    if f(B) | f(B') | f(D) | f(D')
                        F = char(c);
                    end
                end
            end
        end
    end
end

La premessa di base è costruire una maschera booleana per ogni possibile percorso valido e restituire qualsiasi carattere la cui funzione di indice nella matrice copre qualsiasi maschera. Per fare ciò, vengono create solo maschere a forma di barra rovesciata verticale o dall'alto verso il basso, ma la matrice della foresta viene confrontata in tutti e quattro gli orientamenti: identità, capovolto, ruotato di 90 °, capovolto ruotato di 90 °.

La funzione funziona per qualsiasi n. Un esempio di ciò che viene invocato sulla riga di comando è

x('13 anehcienwlndmbaneiryeivownbnabncmxlriruanhahirrnraucriwuafuvocvncriwnbaueibnxzhyirorairenerruwiiwuauawoeqnnvcizdaiehriefyioeorauviquoeuroenraibcuivoaisdfuaeefoiebnxmcsua')

ans =

    a

3

Python - 384 325 275

Questo algoritmo controlla sostanzialmente la prima e l'ultima riga della matrice per la corrispondenza dei caratteri e quindi calcola la lunghezza di ogni segmento di linea

012345
------
aaVaaa|0
aaVaaa|1
aaaVaa|2
aaaVaa|3
aaaaVa|4
aaaaVa|5

Nell'esempio sopra:
la V nella prima riga è nell'indice 2, la V nell'ultima riga nell'indice 4.
Quindi la lunghezza di ogni segmento di linea sarebbe n / (4-2) +1 = 2 con n = 6 .

Quindi controlla se la linea è valida.

Per trovare un percorso da sinistra a destra, scambia le righe con le colonne e fa di nuovo la stessa cosa.

Modifica: impossibile arrivare a 270 (Accidenti a Python e alla tua dannata indentazione !!)

n,m=raw_input().split()
n,r=int(n),range
t=r(n)
a=[m[i:i+n]for i in r(0,n*n,n)]
for v in a,["".join([a[i][j]for i in t])for j in t]:
 for i in t:
  for j in t:
   p=1-2*(j-i<0);d,c=p*(j-i)+1,v[0][i]
   if 6<=sum([v[z][i+(z/(n/d))*p*(n%d==0)]==c for z in t])==n:print c;exit()
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.