Disegna i miei contorni


25

Data una matrice rettangolare di elevazioni, disegna i suoi contorni.

Compito

Due elementi xe ysono sullo stesso livello di contorno se floor(x/10) == floor(y/10). Ad esempio, 52e si 58trovano sullo stesso livello di contorno, ma 58e64 non sono.

L'atto di disegnare contorni è definito come segue: per ogni elemento e, sostituirlo con una stringa di due caratteri scelta come segue:

  • il primo carattere è " "se l'elemento in basso si etrova sullo stesso livello di contorno eo se non vi è alcun elemento in basso ee in "_"altro modo
  • il secondo carattere è " "se l'elemento a destra di si etrova sullo stesso livello di contorno di eo non vi è alcun elemento a destra di ee "|"altrimenti

Gli elementi all'interno delle righe vengono uniti, quindi le righe vengono unite insieme a nuove righe.

Esempio

Diciamo che l'input è [[5,20],[3,6]], visualizzato come

5 20
3 6

Per prima cosa guardiamo 5. Poiché si 3trova sullo stesso livello del contorno 5, il primo carattere è " ". Poiché 20non si trova sullo stesso livello del contorno 5, il secondo carattere è"|" .

Adesso guardiamo 20. Poiché 6non si trova sullo stesso livello del contorno 20, il primo carattere è "_". Poiché non vi è alcun elemento a destra di 20, il secondo carattere è" " .

Adesso guardiamo 3. Poiché non vi è alcun elemento in basso 3, il primo carattere è " ". Poiché si 6trova sullo stesso livello del contorno 3, il secondo carattere è" " .

Adesso guardiamo 6. Poiché non vi è alcun elemento in basso 6, il primo carattere è " ". Poiché non vi è alcun elemento a destra di 6, il secondo carattere è" " .

Sulla base di queste stringhe a due caratteri, eseguiamo sostituzioni per ottenere [[" |","_ "],[" "," "]]. Unendo questi insieme, otteniamo un risultato di

 |_ 
    

Regole

  • La matrice di input sarà sempre rettangolare e composta da numeri interi positivi.
  • Gli spazi finali o le nuove righe possono essere in qualsiasi importo (incluso 0) e non devono essere coerenti in alcun modo.
  • Non è necessario seguire lo stesso algoritmo finché si producono gli stessi risultati.
  • Il programma o la funzione può generare una stringa separata da una nuova riga, un elenco di stringhe o equivalente.
  • Questo è , quindi vince il codice più breve in byte.

Casi test

input
output

[[1,5,8,9],[3,11,13,8],[7,14,10,9],[4,8,7,6]]
  _ _  
 |   | 
 |_ _| 

[[0,10,20,30,40,50,60,70,80,90],[0,0,10,10,20,20,30,30,40,40],[0,0,0,10,10,10,20,20,20,30],[0,0,0,0,10,10,10,10,20,20],[0,0,0,0,0,10,10,10,10,10],[0,0,0,0,0,0,10,10,10,10],[0,0,0,0,0,0,0,10,10,10],[0,0,0,0,0,0,0,0,10,10],[0,0,0,0,0,0,0,0,0,10],[0,0,0,0,0,0,0,0,0,0]]
 |_|_|_|_|_|_|_|_|_
   |_  |_ _|_ _|_ _
     |_    |_ _  |_
       |_      |_ _
         |_        
           |_      
             |_    
               |_  
                 |_


[[5,5,5,5,5,5,5,5,5,5,5],[5,10,10,10,10,10,10,10,10,10,5],[5,10,15,15,15,15,15,15,15,10,5],[5,10,15,20,20,20,20,20,15,10,5],[5,10,15,20,25,25,25,20,15,10,5],[5,10,15,20,25,30,25,20,15,10,5],[5,10,15,20,25,25,25,20,15,10,5],[5,10,15,20,20,20,20,20,15,10,5],[5,10,15,15,15,15,15,15,15,10,5],[5,10,10,10,10,10,10,10,10,10,5],[5,5,5,5,5,5,5,5,5,5,5]]
  _ _ _ _ _ _ _ _ _  
 |                 | 
 |    _ _ _ _ _    | 
 |   |         |   | 
 |   |    _    |   | 
 |   |   |_|   |   | 
 |   |         |   | 
 |   |_ _ _ _ _|   | 
 |                 | 
 |_ _ _ _ _ _ _ _ _| 

[[35,32,29,26,25,25,25,26,29,32,35],[32,28,25,22,20,20,20,22,25,28,32],[29,25,21,18,15,15,15,18,21,25,29],[26,22,18,14,11,10,11,14,18,22,26],[25,20,15,11,7,5,7,11,15,20,25],[25,20,15,10,5,0,5,10,15,20,25],[25,20,15,11,7,5,7,11,15,20,25],[26,22,18,14,11,10,11,14,18,22,26],[29,25,21,18,15,15,15,18,21,25,29],[32,28,25,22,20,20,20,22,25,28,32],[35,32,29,26,25,25,25,26,29,32,35]]
  _|             |_  
_|    _ _ _ _ _    |_
    _|         |_    
   |    _ _ _    |   
   |   |     |   |   
   |   |     |   |   
   |   |_ _ _|   |   
   |_           _|   
_    |_ _ _ _ _|    _
 |_               _| 
   |             |  

1
Non ho nemmeno iniziato a leggere questo prima di rendermi conto di quanto sarebbe bello
Christopher,

Risposte:


6

Perl 6 , 135 byte (131 caratteri)

{my$n="_";sub w{$^a.chop-$^b.chop??$n!!" "};my&q={|.[1..*],.tail};(($_ «[&w]».&q) ZZ~{$n="|";$_ «[&w]».map(*.&q)}()).map:{say |$_}}

Provalo online!

Leggermente non golfato:

{
    my $n = "_";
    sub w { $^a.chop - $^b.chop ?? $n !! " "};
    my &q = {|.[1..*],.tail};
    (
        ($_ «[&w]».&q)
        ZZ~
        {$n="|";$_ «[&w]».map(*.&q)}()
    ).map:{say |$_}
}

Spiegazione : Innanzitutto, definiamo una variabile $n(riga 2) e una funzione w(riga 3). Questa funzione restituisce uno spazio se i suoi due argomenti sono alla stessa "elevazione" e il contenuto della variabile$n altrimenti. Invece di dividere per 10 e pavimentare, abusiamo del fatto che gli ints sono Cool(possono essere trattati come stringhe) e li usanochop per rimuovere l'ultimo carattere (= cifra). Quindi li sottraggiamo con calma, costringendoli di nuovo a numeri: -.

Dopodiché (riga 4) creiamo una funzione q che accetta un elenco e restituisce tale elenco con il primo elemento rimosso e l'ultimo elemento duplicato.

Sulle 3 righe successive, faremo altre 2 matrici dalla matrice di input: la prima ha la prima riga mancante e l'ultima riga è duplicata (questo è solo .&q- usando .&, puoi chiamare una funzione su qualsiasi cosa come se fosse un metodo - la cosa davanti al punto è quindi il primo argomento), l'altro ha la prima colonna mancante e l'ultima colonna duplicata (cioè .map(*.&q)).

Per prima cosa (linea 4) prendiamo la matrice originale $_, la "sovrapponiamo" con la matrice "righe spostate" e usiamo la funzione wcome operatore binario (che è quello [&w]) sugli elementi corrispondenti. Quello mette un _ovunque gli elementi corrispondenti si trovano sulle diverse elevazioni e un altro. Quindi otteniamo ½ del risultato (solo i "primi caratteri").

In linea 6, facciamo la stessa cosa, ma primo cambiamento che abbiamo $na |, e noi ora "overlay" la matrice originale con la matrice con le colonne spostate. Il risultato ha a| a quote diverse e alle stesse. Questi sono i "secondi personaggi".

Ora li combiniamo insieme. Comprimiamo le matrici con una cerniera con un concat (sì ...), che si traduce in una matrice della forma originale il cui ogni elemento sono i 2 elementi corrispondenti delle "mezze soluzioni" concatenate. Infine, eseguiamo la mappatura su questa matrice (che è in realtà un elenco di elenchi). Ognuno di questi elenchi viene appiattito e quindi modificato say(stampato con una nuova riga). Dal momento che saypuò accettare qualsiasi numero di argomenti e li stampa tutti senza separatori, rendendo la nuova riga solo alla fine, otteniamo l'immagine desiderata su stdout. (E il blocco restituisce un elenco di Trues (ognuno sayrestituisce uno True), ma a chi importa.)


+1 perbut who cares
HyperNeutrino,

5

Gelatina ,  25 23  22 byte

-1 byte grazie alle miglia ( Ivettorializza)

:⁵I;€0ao⁶
Zç”_Zż"ç”|$Y

Un programma completo che stampa il risultato. Come collegamento monadico prende un elenco di elenchi di numeri, elevazioni e restituisce un elenco di elenchi, tuttavia queste "righe" sono costituite da elenchi di due "coppie" di caratteri - se questo va bene, è possibile salvare 1 byte rimuovendolo Y.

Provalo online!

Come?

:⁵I;€0ao⁶ - Link 1, assignCharacters (row-wise): list of lists of numbers; character, c
 ⁵        - literal 10
:         - integer division (vectorises)
  I       - incremental differences (vectorises) (zero if the same else non-zero)
     0    - literal 0
   ;€     - concatenate for €ach (rightmost edge of a row has no contour mark)
      a   - logical and (vectorises) with c (replace non-zeros with the contour character)
        ⁶ - literal space character
       o  - logical or (vectorises) (replace the zeros with spaces)

Zç”_Zż"ç”|$Y - Main link: list of lists of numbers, contours
Z            - transpose the input (get the columns)
  ”_         - literal underscore character, '_'
 ç           - call the last link (1) as a dyad with '_'
    Z        - transpose the result
          $  - last two links as a monad:
        ”|   -   literal pipe character, '|'
       ç     -   call the last link (1) as a dyad with '|'
      "      - zip with the dyadic operation:
     ż       -   zip (interleave the column-wise characters with the row-wise ones)
           Y - join with newlines
             - implicit print

grr 3 byte. +1 ma cercherò di superarti;)
HyperNeutrino,

Soluzione indipendente: ho appena visto che la tua è molto simile! te ne salva subito uno ...
Jonathan Allan,

È possibile salvare un byte utilizzando ciascuno sul join nell'helper :⁵I;€0ao⁶anziché nel collegamento principaleZç”_Zż"ç”|$Y
miglia

@miles Oh wow, funziona? Grazie! Immaginavo Iche non sarebbe stato così.
Jonathan Allan,

Sì, Ivettorializza alla profondità 1, ed entrambi ae ovettorializza alla profondità 0
miglia

3

Python 2 , 199 186 157 155 byte

lambda a:(lambda x:'\n'.join(''.join('_ '[x==z]+'| '[x==y]for x,y,z in zip(r,r[1:]+r[-1:],q))for r,q in zip(x,x[1:]+x[-1:])))([[v/10for v in r]for r in a])

Provalo online!


3

Gelatina , 24 byte

:⁵IṠ;€0
ZÇZị⁾_ +³Ç¤ị⁾| ¤

Provalo online!

Spiegazione

:⁵IṠ;€0           Helper Link; get contour data
:                 Floor division by
 ⁵                10
  I               Compute increments
   Ṡ              Sign; ±1 for different values and 0 for same values
    ;             Append
      0           Zero
     €            To each row
ZÇZị⁾_ +³Ç¤ị⁾| ¤  Main Link
Z                 Zip the input (for vertical contours _)
 Ç                Get the contour data
  Z               Zip the data (because it's zipped from the first Z)
   ị              Index into the string
    ⁾_            "_ "
       +          Add (vectorizing twice) to
        ³ ¤    ¤  Nilad starting from (input)
         Ç        Get contour data (horizontal contours |)
           ị      Index into the string
            ⁾|    "| "

-2 byte grazie a Jonathan Allan


La tua soluzione può effettivamente eliminare il Y- restituirà un elenco di elenchi di caratteri, che credo sia OK (mentre il mio ha coppie all'interno delle "righe").
Jonathan Allan,

@JonathanAllan oh sì vero ... grazie!
HyperNeutrino,

2

Python 2 , 226 byte

l=[[j/10for j in i]for i in input()]
for i,j in enumerate(l[:-1]):print''.join('_ '[h==l[i+1][g]]+'| '[h==j[g+1]]for g,h in enumerate(j[:-1]))+'_ '[j[-1]==l[i+1][-1]]
print''.join(' '+'| '[i==j]for i,j in zip(l[-1],l[-1][1:]))

Provalo online!

Accidenti, è stato un po 'stupido elaborare la logica. Ora vedo Hyper Neutrino che mi ha dato una risposta più breve ma ho speso troppo lavoro per non pubblicarlo. : P

Inoltre, posso solo dire, questo è un modo fantastico per creare arte ASCII. Mi scusi mentre faccio un carico di più di questi.


> ninja'd: amico sono passati 45 minuti
HyperNeutrino il

Sì, non ho guardato le risposte ...: P
totalmente umano il

È possibile salvare 4 byte definendo una variabile enumerateinvece di utilizzare due volte il nome completo.
Jonathan Frech,

218 byte rimuovendo il primo enumerate(ecco, ho dovuto rimuovere alcuni input per poterlo collegare qui)
Felipe Nardi Batista,

2

J, 58 byte

f=.{~0==/@]
[:(,/"2)2 2((' _'f{."1),' |'f{.);.3 1:+<.@%&10

Provalo online!

Una funzione anonima che prende una matrice e genera i contorni.

Devo migliorare qui. Non ho avuto il tempo di provare tutti i casi di test, quindi fatemi sapere se ci sono problemi. Proverò a giocare di più a golf e spiegherò più avanti.

(Rapido) Spiegazione

Funzione di supporto: indicizza in una stringa di lunghezza 2 in base al fatto che il primo elemento di un array a 2 lunghezze sia uguale al secondo. Se è uguale, indicizza nell'elemento zeroth, se è disuguale, indicizza nel primo. Un array di 1 lunghezza viene sempre indicizzato nell'elemento zeroth della stringa.

f=.{~0==/@]

Funzione principale

[:(,/"2)2 2((' _'f{."1),' |'f{.);.3 1:+<.@%&10

1:+<.@%&10 ogni elemento viene diviso per 10 e aggiunge 1 (quindi non otterremo mai 0 - questo è importante per la funzione helper).

2 2((' _'f{."1),' |'f{.);.3 taglia la matrice in 2 x 2 segmenti se può (altrimenti darà un segmento 2 x 1, 1 x 2 o 1 x 1 vicino ai bordi) e applica la funzione che utilizza f per confrontare l'elemento in alto a sinistra in alto a destra e l'elemento in alto a sinistra in basso a sinistra.

(,/"2)appiattisce il risultato nella forma desiderata. Sento davvero che dovrei essere in grado di evitare di dover usare questo (e molte altre cose, ma sto divagando).



2

JavaScript (ES6), 120 118 byte

a=>a.map(b=>b.map(c=>c/10|0)).map((b,i,a)=>b.map((c,j)=>((a[i+1]||0)[j]-c?'_':' ')+(b[j+1]-c?'|':' ')).join``).join`\n`

Dove \nrappresenta il carattere letterale di newline. Modifica: salvato 2 byte grazie a @ Bálint.

f=
a=>a.map(b=>b.map(c=>c/10|0)).map((b,i,a)=>b.map((c,j)=>((a[i+1]||0)[j]-c?'_':' ')+(b[j+1]-c?'|':' ')).join``).join`
`
;[
[[5,20],[3,6]]
,
[[1,5,8,9],[3,11,13,8],[7,14,10,9],[4,8,7,6]]
,
[[0,10,20,30,40,50,60,70,80,90],[0,0,10,10,20,20,30,30,40,40],[0,0,0,10,10,10,20,20,20,30],[0,0,0,0,10,10,10,10,20,20],[0,0,0,0,0,10,10,10,10,10],[0,0,0,0,0,0,10,10,10,10],[0,0,0,0,0,0,0,10,10,10],[0,0,0,0,0,0,0,0,10,10],[0,0,0,0,0,0,0,0,0,10],[0,0,0,0,0,0,0,0,0,0]]
,
[[5,5,5,5,5,5,5,5,5,5,5],[5,10,10,10,10,10,10,10,10,10,5],[5,10,15,15,15,15,15,15,15,10,5],[5,10,15,20,20,20,20,20,15,10,5],[5,10,15,20,25,25,25,20,15,10,5],[5,10,15,20,25,30,25,20,15,10,5],[5,10,15,20,25,25,25,20,15,10,5],[5,10,15,20,20,20,20,20,15,10,5],[5,10,15,15,15,15,15,15,15,10,5],[5,10,10,10,10,10,10,10,10,10,5],[5,5,5,5,5,5,5,5,5,5,5]]
,
[[35,32,29,26,25,25,25,26,29,32,35],[32,28,25,22,20,20,20,22,25,28,32],[29,25,21,18,15,15,15,18,21,25,29],[26,22,18,14,11,10,11,14,18,22,26],[25,20,15,11,7,5,7,11,15,20,25],[25,20,15,10,5,0,5,10,15,20,25],[25,20,15,11,7,5,7,11,15,20,25],[26,22,18,14,11,10,11,14,18,22,26],[29,25,21,18,15,15,15,18,21,25,29],[32,28,25,22,20,20,20,22,25,28,32],[35,32,29,26,25,25,25,26,29,32,35]]
].forEach(a=>document.write(['<pre>','</pre>'].join(f(a))));


Puoi trasformare i (a[i] || [])[j]costrutti in(a[i] || 0)[j]
Bálint,

Inoltre, nell'ultimo join`\n`è stato possibile rimuovere la \nparte e sostituirla con una nuova riga effettiva
Bálint,

114 byte:a=>a.map(b=>b.map(c=>c/10|0)).map((b,i,a)=>b.map((c,j)=>" _"[(a[i+1]||0)[j]-c&1]+" |"[b[j+1]-c&1]).join``).join`<new line here>`
Bálint,

@ Bálint Bah, continuo a dimenticare di fare quella \nparte; Provo in un REPL in modo che le nuove linee letterali si mettano in mezzo.
Neil,

@ Bálint Ma il tuo ultimo suggerimento fallisce per l'esempio originale, che ho aggiunto all'elenco degli output.
Neil,

1

Proton , 202 byte

R=(L=len)+range
k=[map((//)&10,r)for r:eval(input())]
d=(x,y,X,Y)=>X>=L(k)or Y>=L(k[X])or k[x][y]==k[X][Y]
print('\n'.join(map(''.join,[['_ '[d(x,y,x+1,y)]+'| '[d(x,y,x,y+1)]for y:R(k[x])]for x:R(k)])))

Provalo online!

-2 byte grazie a Jonathan Frech
-15 byte passando a Proton invece che a Python 2


È possibile salvare due byte sostituendoli lencon Le definendoli L=len;.
Jonathan Frech,

1

Java 8, 200 170 169 byte

a->{String r="";for(int l=a.length,i=0,j;i<l;i++,r+="\n")for(j=0;j<l;r+=(i>l-2||a[i][j]/10==a[i+1][j]/10?" ":"_")+(j++>l-2||a[i][j-1]/10==a[i][j]/10?" ":"|"));return r;}

Spiegazione:

Provalo qui.

Si noti che la divisione dei numeri interi in Java si eleva automaticamente.

a->{                   // Method with 2D int-array as parameter and String return-type
  String r="";         //  Result-String
  for(int l=a.length,  //  Length of the input array
      i=0,j;           //  Index integers
      i<l;i++,         //  Loop (1) over the rows of the input array
          r+="\n")     //  and append a new-line to the result after every iteration
    for(j=0;j<l;       //   Inner loop (2) over the columns of a row
      r+=              //    Append the String with:
         (i>l-2        //      If it's the last row,
         ||a[i][j]/10==a[i+1][j]/10?
                       //      or the current and next rows are equal floored/10:
          " "          //       Use a space
         :             //      Else:
          "_")         //       Use a "_"
        +              //     Plus
         (j++>l-2      //      If it's the last column in the row,
         ||a[i][j-1]/10==a[i][j]/10?
                       //      or the current and next columns are equal floored/10:
          " "          //       Use a space
         :             //      Else:
          "|")         //       Use "|"
    );                 //   End of column loop (2)
                       //  End of row-loop (1) (implicit / single-line body)
  return r;            //  Return the result-String
}                      // End of method

1

R, 159 byte

f=function(m){M=m%/%10;a=cbind(0,t(apply(M,1,diff)));b=rbind(apply(M,2,diff),0);a[!!a]="|";b[!!b]="_";M[]=gsub("0"," ",paste0(a,b));write(t(M),"",ncol(m),,"")}

Con newline e rientri:

f=function(m){
    M=m%/%10
    a=cbind(0,t(apply(M,1,diff))) #row-wise difference
    b=rbind(apply(M,2,diff),0) #column-wise difference
    a[!!a]="|"
    b[!!b]="_"
    M[]=gsub("0"," ",paste0(a,b)) # M[] is a trick to force the result to have the same structure as M
    write(t(M),"",ncol(m),,"")
    }

Fa la divisione intera della matrice, misura le differenze di riga e di colonna e, quando non è nullo, sostituisce con |e _rispettivamente, quindi incolla entrambi (indolore, grazie alla vettorializzazione di R) e gli output.

Casi test:

> m=matrix(c(0,10,20,30,40,50,60,70,80,90,0,0,10,10,20,20,30,30,40,40,0,0,0,10,10,10,20,20,20,30,0,0,0,0,10,10,10,10,20,20,0,0,0,0,0,10,10,10,10,10,0,0,0,0,0,0,10,10,10,10,0,0,0,0,0,0,0,10,10,10,0,0,0,0,0,0,0,0,10,10,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0),byrow=T,ncol=10)
> f(m)
  |_|_|_|_|_|_|_|_|_
    |_  |_ _|_ _|_ _
      |_    |_ _  |_
        |_      |_ _
          |_        
            |_      
              |_    
                |_  
                  |_

> m=matrix(c(5,5,5,5,5,5,5,5,5,5,5,5,10,10,10,10,10,10,10,10,10,5,5,10,15,15,15,15,15,15,15,10,5,5,10,15,20,20,20,20,20,15,10,5,5,10,15,20,25,25,25,20,15,10,5,5,10,15,20,25,30,25,20,15,10,5,5,10,15,20,25,25,25,20,15,10,5,5,10,15,20,20,20,20,20,15,10,5,5,10,15,15,15,15,15,15,15,10,5,5,10,10,10,10,10,10,10,10,10,5,5,5,5,5,5,5,5,5,5,5,5),byrow=T,ncol=11)
> f(m)
   _ _ _ _ _ _ _ _ _  
  |                 | 
  |    _ _ _ _ _    | 
  |   |         |   | 
  |   |    _    |   | 
  |   |   |_|   |   | 
  |   |         |   | 
  |   |_ _ _ _ _|   | 
  |                 | 
  |_ _ _ _ _ _ _ _ _| 

0

Perl 5 , 130 126 byte

124 byte di codice + 2 per i -apflag

push@a,[map 0|$_/10,@F]}{map{say map{($a[$r+1][$c]-$_&&$r<$#a?'_':$").($a[$r][++$c]-$_&&$c<@{$a[0]}?'|':$")}@$_;$c=0;$r++}@a

Provalo online!

Il formato di input è una griglia 2D di numeri separati da spazi.

Spiegazione

Questo deriva da una precedente iterazione del codice.

push@a,[map 0|$_/10,@F]     # read the input, divide it by 10, and store it in a 2-D array
}{                          # end the implicit while loop and start the final block
map{                        # repeat this for each line
  $_=($a[$r+1][$c]-$_&&$r<$#a?'_':$")       # set appropriate characters to output based
     .($a[$r][++$c]-$_&&$c<@{$a[0]}?'|':$") # on the given rules
  for@$_;                                   # repeat for each number on the line
  $c=0;$r++;                         # setup row and column counters for next iteration
  say@$_                             # output this line
}@a
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.