Parole -> Skyline della città


40

La sfida

Il programma o la funzione accetterà un singolo input di stringa da STDIN o un parametro di funzione. Si può presumere che l'input conterrà solo caratteri alfabetici (a-zA-Z), spazi e stop completi. L'input non fa distinzione tra maiuscole e minuscole, quindi dovresti trattare "a" esattamente come tratteresti "A".

Per ogni carattere nella stringa, verrà emessa una rappresentazione di un edificio secondo le seguenti specifiche.

Ogni edificio deve avere un tetto, indicato da un carattere di sottolineatura nella riga superiore, quindi da una barra, spazio, barra rovesciata nella seconda riga.

 _
/ \

Avrai quindi un numero di piani, corrispondenti al numero di lettera (a = 1, b = 2, c = 3 ecc.) Che sono rappresentati da un muro (|) su ciascun lato e uno spazio nel mezzo. Il piano inferiore (e solo il piano inferiore) dovrebbe avere una fondazione, che è un carattere di sottolineatura tra le pareti. Come questo...

|_|

Ad esempio, "b" sarebbe simile a questo

 _
/ \
| |
|_|

Ora sappiamo che edifici molto alti e stretti non possono sopportare e devono allargarsi alla base, quindi nessun edificio può superare i tre piani senza un supporto aggiuntivo. Quindi ogni tre livelli (non meno) dovresti aggiungere un 'livello di ampliamento'. Lo strato allargato è costituito da una barra e una barra rovesciata direttamente sopra le pareti della sezione sottostante e la sezione sottostante dovrebbe essere due spazi più ampia della sezione sopra. Il livello aggiuntivo non conta per l'altezza dell'edificio.

Gli edifici non devono sovrapporsi ma non devono avere spazi non necessari tra loro e il terreno è sempre piatto, quindi tutti gli edifici dovrebbero avere la loro base allo stesso livello.

Ad esempio, "abcdefga" sarà simile a questo.

                           _
                          / \
                     _    | |
                _   / \   | |
           _   / \  | |   | |
          / \  | |  | |  /   \
       _  | |  | |  | |  |   |
    _ / \ | |  | | /   \ |   |
 _ / \| | | | /   \|   | |   |  _
/ \| || |/   \|   ||   |/     \/ \
|_||_||_||___||___||___||_____||_|

Gli spazi nell'input della stringa devono essere rappresentati da un doppio spazio.

I punti di arresto completi nell'input della stringa devono essere rappresentati da macerie in questo modo.

/\/\

Ulteriori esempi

Input = Hello world.

Uscita =

                                                   _                                                  
                                                  / \                                                 
                                                  | |                                                 
                                                  | |                                                 
                                                  | |                                                 
                                                 /   \                                                
                                                 |   |                                                
                                                 |   |                       _                        
                                                 |   |                      / \                       
                                                /     \                     | |                       
                                                |     |                     | |                       
                                   _            |     |          _          | |                       
                                  / \           |     |         / \        /   \                      
                                  | |          /       \        | |        |   |                      
                                  | |          |       |        | |        |   |                      
                _        _        | |          |       |        | |        |   |        _             
               / \      / \      /   \         |       |       /   \      /     \      / \            
               | |      | |      |   |        /         \      |   |      |     |      | |            
               | |      | |      |   |        |         |      |   |      |     |      | |            
               | |      | |      |   |        |         |      |   |      |     |      | |            
   _          /   \    /   \    /     \       |         |     /     \    /       \    /   \           
  / \         |   |    |   |    |     |      /           \    |     |    |       |    |   |           
  | |         |   |    |   |    |     |      |           |    |     |    |       |    |   |           
  | |         |   |    |   |    |     |      |           |    |     |    |       |    |   |           
  | |    _   /     \  /     \  /       \     |           |   /       \  /         \  /     \          
 /   \  / \  |     |  |     |  |       |    /             \  |       |  |         |  |     |   _      
 |   |  | |  |     |  |     |  |       |    |             |  |       |  |         |  |     |  / \     
 |   |  | |  |     |  |     |  |       |    |             |  |       |  |         |  |     |  | |     
 |   |  | | /       \/       \/         \   |             | /         \/           \/       \ | |     
/     \/   \|       ||       ||         |  /               \|         ||           ||       | | |     
|     ||   ||       ||       ||         |  |               ||         ||           ||       |/   \    
|_____||___||_______||_______||_________|  |_______________||_________||___________||_______||___|/\/\

Input = lorem ipsum

                                                                                             _                  
                                                                                            / \                 
                                                                              _             | |                 
                                                                             / \            | |                 
                          _                                                  | |            | |                 
                         / \                                                 | |           /   \                
                         | |                                    _            | |           |   |                
                         | |                                   / \          /   \          |   |                
              _          | |                                   | |          |   |          |   |                
             / \        /   \                                  | |          |   |         /     \               
             | |        |   |              _                   | |          |   |         |     |         _     
             | |        |   |             / \                 /   \        /     \        |     |        / \    
    _        | |        |   |             | |                 |   |        |     |        |     |        | |    
   / \      /   \      /     \            | |                 |   |        |     |       /       \       | |    
   | |      |   |      |     |            | |                 |   |        |     |       |       |       | |    
   | |      |   |      |     |           /   \               /     \      /       \      |       |      /   \   
   | |      |   |      |     |           |   |        _      |     |      |       |      |       |      |   |   
  /   \    /     \    /       \          |   |       / \     |     |      |       |     /         \     |   |   
  |   |    |     |    |       |          |   |       | |     |     |      |       |     |         |     |   |   
  |   |    |     |    |       |         /     \      | |    /       \    /         \    |         |    /     \  
  |   |    |     |    |       |         |     |      | |    |       |    |         |    |         |    |     |  
 /     \  /       \  /         \   _    |     |     /   \   |       |    |         |   /           \   |     |  
 |     |  |       |  |         |  / \   |     |     |   |   |       |    |         |   |           |   |     |  
 |     |  |       |  |         |  | |  /       \    |   |  /         \  /           \  |           |  /       \ 
 |     |  |       |  |         |  | |  |       |    |   |  |         |  |           |  |           |  |       | 
/       \/         \/           \ | |  |       |   /     \ |         |  |           | /             \ |       | 
|       ||         ||           |/   \ |       |   |     | |         |  |           | |             | |       | 
|       ||         ||           ||   |/         \  |     |/           \/             \|             |/         \
|_______||_________||___________||___||_________|  |_____||___________||_____________||_____________||_________|

Input = a.a.a.x.x.x.a.a.a

                             _                    _                    _                             
                            / \                  / \                  / \                            
                            | |                  | |                  | |                            
                            | |                  | |                  | |                            
                            | |                  | |                  | |                            
                           /   \                /   \                /   \                           
                           |   |                |   |                |   |                           
                           |   |                |   |                |   |                           
                           |   |                |   |                |   |                           
                          /     \              /     \              /     \                          
                          |     |              |     |              |     |                          
                          |     |              |     |              |     |                          
                          |     |              |     |              |     |                          
                         /       \            /       \            /       \                         
                         |       |            |       |            |       |                         
                         |       |            |       |            |       |                         
                         |       |            |       |            |       |                         
                        /         \          /         \          /         \                        
                        |         |          |         |          |         |                        
                        |         |          |         |          |         |                        
                        |         |          |         |          |         |                        
                       /           \        /           \        /           \                       
                       |           |        |           |        |           |                       
                       |           |        |           |        |           |                       
                       |           |        |           |        |           |                       
                      /             \      /             \      /             \                      
                      |             |      |             |      |             |                      
                      |             |      |             |      |             |                      
                      |             |      |             |      |             |                      
                     /               \    /               \    /               \                     
 _      _      _     |               |    |               |    |               |     _      _      _ 
/ \    / \    / \    |               |    |               |    |               |    / \    / \    / \
|_|/\/\|_|/\/\|_|/\/\|_______________|/\/\|_______________|/\/\|_______________|/\/\|_|/\/\|_|/\/\|_|

Regole

  • Naturalmente questo è il codice golf, il punteggio più basso in byte vince
  • Si applicano le regole standard per le scappatoie
  • È consentito qualsiasi numero di righe vuote aggiuntive prima o dopo l'output
  • È possibile scegliere di produrre l'intero risultato in una stringa o offrire l'output come un array in cui ogni elemento rappresenta una riga di output oppure inviare a STDOUT

Nota

Questo è il mio primo post su PPCG, quindi per favore andate piano con me. È stato attraverso la sandbox. Eventuali punti negativi o possibili miglioramenti si prega di pubblicare come commento e farò quello che posso


7
Conversione [a,z]e [A,Z]per [1,26]sembra un requisito inutile. Sarebbe molto meglio usare un intero elenco come input (essendo 0l'input per le macerie). Inoltre, pubblicare la tua sfida dopo essere stata nella Sandbox per sole 21 ore , senza aspettare di ottenere voti o feedback da più di un utente, non conta come "passata attraverso la sandbox". Si consiglia di lasciare le sfide nella Sandbox per almeno 48-72 ore, per dare alle persone un sacco di tempo per esaminarle.
Mego

2
Mi ricorda questo . Nizza prima sfida, ma vi consiglio di pensare di cambiare il [a,z], [1.26]parti della Mego menzionati. Avere facoltativo è spesso il migliore (a meno che non sia una parte fondamentale della sfida (non è qui).
Stewie Griffin

2
Dirò, questa è una prima bella sfida. Benvenuti nel sito!
DJMcMayhem

1
Riesco a capire il punto sulla mappatura az in numeri interi. Aveva senso nella prima iterazione della sfida, ma dal momento che il montaggio per chiarezza e brevità (c'era un retroscena che ho rimosso) le lettere non sono più rilevanti. Modificherò opportunamente il prima possibile
Darren H

1
Preferisco az, spazio, punto, personalmente.
isaacg,

Risposte:


10

JavaScript (ES6), 330 326 ... 315 309 byte

Costruisce l'arte ASCII in modo ricorsivo, iniziando dal piano inferiore e applicando diverse espressioni regolari tra ogni fase:

(a,l,R=(E,b)=>E.split`:`.map((e,i)=>l=(l||a).replace(RegExp(e,'g'),b?b.split`:`[i]:n=>(x=(n.charCodeAt()-65)%32)<0?x+1?'/y/y':n+n:x%3+'_'.repeat((x/3<<1)+1)+0)))=>(L=l)?(R('/y:_:/xy:1:2:/xx(x+)y:0(x+)0:3','  :x: _ :3:1: 2$10 :/$1y:0'),L==l?(l=a.join`
`,R('\\d:x:y','|: :\\'),l):f([l].concat(a),l)):f(R('.'),l)

Come funziona

1) piano inferiore

Iniziamo traducendo la stringa di input in un piano inferiore come:

"ab cd.df.hcab"  -->  "0_01_0  2_00___0/y/y0___02___0/y/y1_____02_00_01_0"

dove:

  • y è un alias più breve per la barra rovesciata (che richiede l'escaping)
  • La cifra ( 0, 1o 2) poco prima di una sequenza _è la parete sinistra dell'edificio. Rappresenta il numero di muri che devono essere posizionati sopra di esso prima del successivo "strato di ampliamento".
  • La cifra dopo una sequenza di _è la parete destra dell'edificio ed è sempre impostata su 0.

2) Espressioni regolari applicate tra ogni fase

Il processo ricorsivo consiste nell'applicare 9 sostituzioni al piano precedente, usando le seguenti espressioni regolari:

  1. /\/y/g=> " "(rimuovi le macerie)
  2. /_/g=> "x"(sostituisci la fondazione o la parte superiore dell'edificio con un blocco solido)
  3. /\/xy/g=> " _ "(sostituisci l'ultimo livello di ampliamento con la parte superiore dell'edificio)
  4. /1/g=> "3"(sostituisci temporaneamente 1con 3- vedi l'ultimo passaggio)
  5. /2/g=> "1"(sostituisci 2con 1)
  6. /\/xx(x+)y/g=> " 2$10 "(sostituisci uno strato allargato con un nuovo muro più stretto)
  7. /0(x+)0/g=> "/$1y"(sostituisci la parte superiore del muro con uno strato allargante)
  8. /3/g=> "0"(sostituisci 3con 0)

Ad esempio, ecco le successive trasformazioni di 2___0(piano inferiore generato da a 'f'):

"2___0" > "1xxx0" > "0xxx0" > "/xxxy" > " 2x0 " > " 1x0 " > " 0x0 " > " /xy " > "  _  "

                                                                                   _   
                                                                        /xy       /xy  
                                                              0x0       0x0       0x0  
                                                    1x0       1x0       1x0       1x0  
                                          2x0       2x0       2x0       2x0       2x0  
                               /xxxy     /xxxy     /xxxy     /xxxy     /xxxy     /xxxy 
                     0xxx0     0xxx0     0xxx0     0xxx0     0xxx0     0xxx0     0xxx0 
           1xxx0     1xxx0     1xxx0     1xxx0     1xxx0     1xxx0     1xxx0     1xxx0 
 2___0     2___0     2___0     2___0     2___0     2___0     2___0     2___0     2___0 

NB : la parte superiore dell'edificio viene quindi sostituita da a x. Questo non è mostrato nel diagramma sopra.

3) Espressioni regolari applicate al risultato finale

La ricorsione si interrompe quando non c'è altro da sostituire, il che significa che siamo oltre la cima dell'edificio più alto.

Ora dobbiamo ripulire tutto con ancora qualche altra espressione regolare:

  1. /\d/g=> "|"(sostituisci le cifre con i tubi)
  2. /x/g=> " "(sostituisce i blocchi solidi con spazi)
  3. /y/g=> "\"(sostituisci ycon barre rovesciate)

Per esempio:

  _            _  
 /xy          / \ 
 0x0          | | 
 1x0          | | 
 2x0   -->    | | 
/xxxy        /   \
0xxx0        |   |
1xxx0        |   |
2___0        |___|

dimostrazione

let f =

(a,l,R=(E,b)=>E.split`:`.map((e,i)=>l=(l||a).replace(RegExp(e,'g'),b?b.split`:`[i]:n=>(x=(n.charCodeAt()-65)%32)<0?x+1?'/y/y':n+n:x%3+'_'.repeat((x/3<<1)+1)+0)))=>(L=l)?(R('/y:_:/xy:1:2:/xx(x+)y:0(x+)0:3','  :x: _ :3:1: 2$10 :/$1y:0'),L==l?(l=a.join`
`,R('\\d:x:y','|: :\\'),l):f([l].concat(a),l)):f(R('.'),l)

console.log(f('ab cd.df.hcab'));

Collaboratori:
4 byte salvati grazie a Hedi
8 byte salvati grazie a Not that Charles


Chiunque desideri inserire un input come numero intero è il benvenuto, ma suggerirei che tale voce dovrebbe essere non competitiva
mbomb007

@ mbomb007 - Questo problema è stato risolto. Le mie attuali ottimizzazioni non compensano il costo del famigerato .charCodeAt().
Arnauld,

Non è necessario new innew RegExp(e,'g')
Hedi,

Mi piace molto questo approccio. Alcune idee che possono aiutare: 1. utilizzare un carattere come yquello che non richiede fuga per la barra. 2. se si utilizza _per il piano terra, è ancora possibile distinguere la parte superiore con la regex: /_ /.
Non che Charles, il

1
@NotthatCharles - In realtà non ho mai notato la regola del "doppio spazio". ;) Questo è stato risolto.
Arnauld,

7

PHP, 386 376 367 364 362 358 356 byte

primo approccio; potrebbe essere ancora golfabile.

foreach(str_split($argv[1])as$c)for($n=28,$w='.'!=$c?1+2*ceil(1/3*$n=31&ord($c)):4,$p=$y=0;$y<36;){$s=str_pad("",$w,$y||!$n?" ":_);if($n>26&&!$y){$s="/\\/\\";$n=-1;}elseif($n-->0){$s[$p]=$s[$w-$p-1]="|";if($n%3<1){$o[$y++].=$s;$s=str_pad("",$w);$s[$p]="/";$s[$w-++$p]="\\";}}$o[$y++].=$s;if(!$n)$o[$y++].=str_pad(_,$w," ",2);}for($y=36;$y--;)echo"$o[$y]
";

PHP, 366 362 361 360 357 byte

approccio simile con una sottofunzione:

function a($p,$r){global$o,$w,$y;$o[$y++].=str_pad(str_pad($r[0],2*$p,$r[1]).$r[2],$w," ",2);}foreach(str_split($argv[1])as$i=>$c)for($n=28,$w='.'!=$c?1+2*$p=ceil(1/3*$n=31&ord($c)):$p=4,$y=0;$y<36;)if($n>26&&!$y)$o[$n=$y++].="/\\/\\";elseif($n-->0){a($p,$y?"| |":"|_|");if($n%3<1)a($p--,"/ \\");if(!$n)a(1," _");}else a(0,"");for($y=36;$y--;)echo"$o[$y]
";

ripartizione per il secondo approccio

function a($p,$r)
{
    global$o,$w,$y;
    $o[$y++].=                  // 3. add result to current line, increase line counter
        str_pad(                // 2. pad ...
        str_pad($r[0],2*$p,$r[1]).$r[2]     // 1. A + inner width(=2*$p-1) times B + C
        ,$w," ",2);             // ... to $w with blanks on both sides # 2==STR_PAD_BOTH
}

foreach(str_split($argv[1])as$i=>$c)
    for(
    $n=28,
    $w='.'!=$c                          // $w=total width
        ?1+2*$p=ceil(1/3*$n=31&ord($c)) // $n=storey count, $p=(inner width+1)/2
        :$p=4                           // $n=28, $p <= $w=4 for rubble
    ,
    $y=0;$y<36;)                        // $y=line counter
        if($n>26&&!$y)
            $o[$n=$y++].="/\\/\\";      // bottom line=rubble, $n=0
        elseif($n-->0)
        {
            a($p,$y?"| |":"|_|");       // add storey
            if($n%3<1)a($p--,"/ \\");   // add widening layer/roof
            if(!$n)a(1," _");           // add roof top
        }
        else
            a(0,"");                    // idk why str_pad doesn´t yield a warning here

for($y=36;$y--;)if($s=rtrim($o[$y]))echo"$s\n"; // output

+16 byte se non sono consentite nuove righe iniziali:
sostituire echo"$o[$y]\n;con if($s=rtrim($o[$y]))echo"$s\n";.

-3 byte per qualsiasi delle ;<=>?[\]^_{|}~macerie: sostituire 1) ($n=31&ord($c))con $n, 2) $n=28,$w='.'!=$ccon ($n=31&ord($c))<27e 3) 4con ($n=28)/7.

Un altro -8 per >, ^o ~come macerie: Annulla 3)


1
if(!$n){$o[$y++].=str_pad(_,$w," ",2);}-2 byte per le parentesi quadre
Jörg Hülsermann,

e l'uscita può essere fatto 3 byte corta: for($y=36;$y--;)echo"$o[$y]\n";; ma ho un nuovo approccio che salva altri 2 byte.
Tito,

1
php.net/manual/en/functions.anonymous.php per il secondo approccio `funzione a ($ p, $ r) use ($ o, $ w, $ y) 'anziché globale
Jörg Hülsermann

@ JörgHülsermann: usefunziona solo per funzioni anonime. risparmierebbe 2 byte; ma dovrei memorizzare quella funzione in una variabile $a=invece di dargli un nome (+3 byte) e aggiungere un $a ciascuna delle quattro chiamate.
Tito,

4

Pyth, 93 79 byte

K"/\\"j_.tsm?hJxGdC_m.[hyNk\ +\_mj*hy/k4?nkJ\ \_?%k4"||"Kh=+J=Nh/J3[F*2|@d;Krz0

Provalo online. Suite di test.

Spiegazione

L'ho nascosto per impostazione predefinita poiché è troppo lungo.


4

Perl, 147 146 byte

Include +1 per -p

Esegui con input su STDIN, ad es

citysky.pl <<< " abcdefgxyz."

citysky.pl:

#!/usr/bin/perl -p
s%.%@{[map chr~-ord(lc$&)*4/3-4*(abs||-9),-9..9]}%g;y/M\xa248
A|-\xc6\0-\xff/MA||
A}-\xc6A/d,$a=(lc$a).$_ for($_)x36;*_=a;s/\x9f.*?\K\x9f/\xa3/g;y%A\xc6\x9f-\xa3\x0b-\xff%__/|||\\ %

Funziona come mostrato, ma sostituisci le \xhhfughe con il loro valore letterale per ottenere il punteggio richiesto. Puoi farlo usando questa riga di comando:

perl -0pi -e 's/\\x(..)/chr hex $1/eg;s/\n$//' citysky.pl

Non ho davvero esplorato altri approcci, quindi potrebbe essere molto battibile ...


2

Haskell, 289 byte

c?l=c++l++c
c%s=("|"?(drop 2(r s)>>c)):s
g 46=["/\\"?""]
g 32=["  "]
g x="_"%h(mod x 32)
h 1=["/ \\"," _ "]
h x=(" "%h(x-1))!x
v!x|mod x 3/=1=v|z<-'/':r v++"\\"=z:map(" "?)v
r v=v!!0>>" "
f t|l<-map(g.fromEnum)t,m<-maximum(map length l)-1=unlines[l>>= \x->(x++cycle[r x])!!i|i<-[m,m-1..0]]

2

Ruby, 245

->s{a=['']*36
w=' '
s.chars{|c|a[u=0]+=c<?!?w*2:c<?/?"/\\"*2:(h=c.upcase.ord-64
1.upto(1+h+=(h-1)/3){|t|u=[u,l=1+2*((f=h-t)/4)].max
a[t]+=w*(a[0].size-a[t].size)+(f<-1?w:f<0??_:(f%4<1?[?/,?\\]:[?|]*2)*(w*l)).center(u+2)}
"|#{?_*u}|")}
a.reverse}

Consenti tutte le nuove linee extra che desideri, quindi mi prenderò la libertà. A parte questo, il processo è il seguente:

  1. Inizializza un array di output a.
  2. Per ogni carattere:
    1. se è "", aggiungi  aa[0]
    2. se è ".", aggiungi /\/\aa[0]
    3. altrimenti:
      1. calcola l'altezza ( c.upcase.ord + (c.upcase.ord-1)/3)
      2. per ogni riga in a:
        1. riempire la riga con spazi bianchi. a[t]+=w*(a[0].size-a[t].size)
        2. se siamo uno sopra h, al centro a_
        3. altrimenti se siamo sopra l'altezza, al centro a 
        4. altrimenti se siamo sotto l'altezza, il centro | |o / \la larghezza corretta ( 1+2*((h-t)/4), a seconda seh-t%4==0
        5. aggiungi "|___|"la larghezza giusta aa[0]
  3. ritorno a.reverse

Scommetto che riesco a rimpicciolirlo se risolvo la matematica per evitarlo reverse


2

PHP, 297 byte

foreach(str_split($argv[1])as$c)for($j=0,$h=ord($c)-64,$g=$h+$f=ceil($h/3),$w=$v=$h<0?$h<-18?2:4:2*$f+1;$j<36;$j++,$g--,$v-=$h>0&&$v>1?($g%4||!$j)?0*$n="|$s|":2+0*$n="/$s\\":$v+0*$n=['','_','',0,'/\/\\'][$v],$o[$j].=str_pad($n,$w,' ',2))$s=str_repeat($j?' ':'_',$v-2);krsort($o);echo join($o,'
');

Una versione più leggibile:

foreach (str_split($argv[1]) as $character) {
    for (
        $line = 0,
        $buildingHeight = ord($character) - 64,
        $floorsLeft = $buildingHeight + $supportFloors = ceil($buildingHeight / 3),
        $buildingWidth = $widthOnThisFloor = $buildingHeight < 0
            ? $buildingHeight < -18
                ? 2
                : 4
            : 2 * $supportFloors + 1;

        $line < 36;

        // The body of the for-loop is executed between these statements

        $line++,
        $floorsLeft--,
        $widthOnThisFloor -= $buildingHeight > 0 && $widthOnThisFloor > 1
            ? ($floorsLeft % 4 || !$line)
                ? 0 * $floorString = "|$middleSpacing|"
                : 2 + 0 * $floorString = "/$middleSpacing\\"
            : $widthOnThisFloor + 0 * $floorString = ['', '_', '', 0, '/\/\\'][$widthOnThisFloor],
        $outputArray[$line] .= str_pad($floorString, $buildingWidth, ' ', 2)
    ) {
        $middleSpacing = str_repeat($line ? ' ' : '_', $widthOnThisFloor - 2);
    }
}
krsort($outputArray);
echo join($outputArray, '
');
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.