Crea un supercrostico


35

sfondo

Festeggiamo il rilascio di Dyalog APL 16.0 , in cui la soluzione a questo problema è la {⊢⌺(≢⍵)⊢⍵}spiegazione

Compito

Data una stringa ASCII stampabile di lunghezza dispari n , crea un quadrato n × n con la stringa centrata orizzontalmente, duplicata per essere centrata verticalmente e con acrostici della stessa stringa in ogni riga e colonna. Si noti che tutte le stringhe tranne quelle centrate verranno tagliate per mantenere la dimensione del quadrato n × n .

La spiegazione del tuo codice sarà molto apprezzata.

Regole

  1. Potresti avere spazi vuoti e newline finali (questo include il triangolo in basso a destra)
  2. È possibile restituire un elenco di stringhe

Esempio usando la stringa ABXCD:

  • n è 5. Innanzitutto disegniamo le due stringhe centrate, una orizzontale e una verticale:

    ┌─────┐
    │ A │
    │ B │
    │ABXCD│
    │ C │
    │ D │
    └─────┘
    

    (5 × 5 riquadro di selezione aggiunto per maggiore chiarezza)

  • Quindi posizioniamo tutti i possibili acrostici, in orizzontale e in verticale:

           UN
          AB
      ┌─────┐
      │ ABX│CD
      │ ABXC│D
      │ABXCD│
     A│BXCD │
    AB│XCD │
      └─────┘
       CD
       D
    
  • Infine, restituiamo solo ciò che è all'interno del riquadro di selezione:

      ABX
     ABXC
    ABXCD
    BXCD 
    XCD  
    

Casi test

World:

  Wor
 Worl
World
orld
rld

mississippi:

     missis
    mississ
   mississi
  mississip
 mississipp
mississippi
ississippi
ssissippi
sissippi
issippi
ssippi

Pneumonoultramicroscopicsilicovolcanoconiosis:

                      Pneumonoultramicroscopi
                     Pneumonoultramicroscopic
                    Pneumonoultramicroscopics
                   Pneumonoultramicroscopicsi
                  Pneumonoultramicroscopicsil
                 Pneumonoultramicroscopicsili
                Pneumonoultramicroscopicsilic
               Pneumonoultramicroscopicsilico
              Pneumonoultramicroscopicsilicov
             Pneumonoultramicroscopicsilicovo
            Pneumonoultramicroscopicsilicovol
           Pneumonoultramicroscopicsilicovolc
          Pneumonoultramicroscopicsilicovolca
         Pneumonoultramicroscopicsilicovolcan
        Pneumonoultramicroscopicsilicovolcano
       Pneumonoultramicroscopicsilicovolcanoc
      Pneumonoultramicroscopicsilicovolcanoco
     Pneumonoultramicroscopicsilicovolcanocon
    Pneumonoultramicroscopicsilicovolcanoconi
   Pneumonoultramicroscopicsilicovolcanoconio
  Pneumonoultramicroscopicsilicovolcanoconios
 Pneumonoultramicroscopicsilicovolcanoconiosi
Pneumonoultramicroscopicsilicovolcanoconiosis
neumonoultramicroscopicsilicovolcanoconiosis
eumonoultramicroscopicsilicovolcanoconiosis
umonoultramicroscopicsilicovolcanoconiosis
monoultramicroscopicsilicovolcanoconiosis
onoultramicroscopicsilicovolcanoconiosis
noultramicroscopicsilicovolcanoconiosis
oultramicroscopicsilicovolcanoconiosis
ultramicroscopicsilicovolcanoconiosis
ltramicroscopicsilicovolcanoconiosis
tramicroscopicsilicovolcanoconiosis
ramicroscopicsilicovolcanoconiosis
amicroscopicsilicovolcanoconiosis
microscopicsilicovolcanoconiosis
icroscopicsilicovolcanoconiosis
croscopicsilicovolcanoconiosis
roscopicsilicovolcanoconiosis
oscopicsilicovolcanoconiosis
scopicsilicovolcanoconiosis
copicsilicovolcanoconiosis
opicsilicovolcanoconiosis
picsilicovolcanoconiosis
icsilicovolcanoconiosis

Ringraziamenti

Grazie a dzaima , Leaky Nun , Mr. Xcoder per tutto tranne l'idea stessa di questa sfida.


1
Gli spazi-triange in basso a destra devono essere inclusi o no?
Flawr,

1
@flawr OP: maggio
Adám,

Risposte:



5

MATL , 8 byte

nXyPGZ+c

Provalo online!

Spiegazione

n    % Implicit input. Number of elements
Xy   % Identity matrix of that size
P    % Flip vertically
G    % Push input again
Z+   % 2D convolution, maintaining size
c    % Convert to char (char 0 is displayed as space). Implicitly display

1
Chi pensava che avrei voluto questa risposta: D
flawr

1
@flawr Sì, chi avrebbe mai pensato
Luis Mendo il

4

Retina , 70 59 byte

.
$.'$* $_$.`$* ¶
(?=((....))+)(?<-1>.)+(.*?)(?<-2>.)+¶
$3¶

Provalo online! Modifica: salvato 11 byte con l'aiuto di @MartinEnder. Spiegazione: Il primo stadio ripete l'input una volta per ogni personaggio, riempiendolo in modo appropriato su ogni riga per ottenere il taglio. L'ultimo stadio rimuove quindi il 25% da ciascun lato per produrre il risultato desiderato.


Penso di averne avuto 59 prima. Non ho tempo di scavare i dettagli ora, ma essenzialmente nella prima fase ho appena riempito l'input con n/2spazi a destra e a sinistra (usando qualcosa come (..)+.-> $#1$* $&$#1$*con uno spazio finale) e poi ho fatto un punto in !&`...cui ...corrispondono nesattamente i ncaratteri.
Martin Ender,

Il tuo approccio può almeno essere ridotto a 63: tio.run/##K0otycxL/…
Martin Ender,

@MartinEnder Grazie e ho giocato a golf con altri 4 byte!
Neil,

Hai bisogno del secondo $*sp?
Calcolatrice

@CalculatorFeline Sì, ho bisogno che tutte le linee abbiano la stessa lunghezza, quindi posso dividerlo per 4.
Neil

3

Java 8, 120 103 byte

s->{int l=s.length(),i=l/2;for(;i-->0;s=" "+s+" ");for(;++i<l;System.out.println(s.substring(i,l+i)));}

-17 byte grazie a @ OlivierGrégoire .

Spiegazione:

Provalo qui.

s->{                      // Method with String parameter and no return-type
  int l=s.length(),       //  Length of the input-String
      i=l/2;              //  Temp index-integer (starting at halve the length floored)
  for(;i-->0;             //  Loop (1) from `l/2` to 0 (exclusive)
    s=" "+s+" "           //   Add spaces before and after the input-String
  );                      //  End of loop (1)
                          //  (If the input was "World", it is now "  World  ")
  for(;++i<l;             //  Loop (2) from 0 to `l` (exclusive)
    System.out.println(   //   Print:
      s.substring(i,      //    Substring of the modified input from `i`
                    l+i)  //    to `l+i` (exclusive)
    )                     //   End of print
  );                      //  End of loop (2)
}                         // End of method

i=l/2+1ed i-->1e for(;i<lsalvare un byte.
Olivier Grégoire,

1
E ... totalmente golfato: s->{int l=s.length(),i=l/2;while(i-->0)s=" "+s+" ";while(++i<l)System.out.println(s.substring(i,l+i));}(103 byte). L'unico cambiamento significativo è che la stringa con spazi viene generata una volta per tutte anziché "al volo" (e ovviamente la stampa invece di tornare).
Olivier Grégoire,

3

Haskell, 64 62 byte

f s|l<-length s=take l$take l<$>scanr(:)""(([2,4..l]>>" ")++s)

Provalo online! Come funziona:

l<-length s               -- let l be the length of the input string

      ([2,4..l]>>" ")     -- take l/2 spaces and
                     ++s  -- append s
    scanr(:)""            -- make a list of the inits of the above string, e.g.
                          -- "  world" -> ["  world"," world","world","orld"...]
  take l <$>              -- take the first l chars of each string
take l                    -- and the first l strings

3

SWI Prolog, 234 byte

h(_,0,_,_,[]).
h(T,N,S,L,[H|U]):-sub_string(T,S,L,_,H),M is N-1,A is S+1,h(T,M,A,L,U).
s(T,R):-string_length(T,L),findall('_',between(1,L,_),A),string_chars(B,A),
                   string_concat(B,T,C),string_concat(C,B,D),S is L-((L-1)/2),h(D,L,S,L,R).

Forse prova online qui: http://swish.swi-prolog.org/p/hEKigfEl.pl

NB.

  1. L'ultima riga è una lunga, ho aggiunto un'interruzione di riga e spazi qui solo per evitare la barra di scorrimento orizzontale in questa risposta.
  2. La domanda riguarda gli spazi per il riempimento, ma Swish online non li mostra in modo pulito a causa delle interazioni di rendering HTML, è necessario visualizzare l'origine negli strumenti di sviluppo del browser per verificare che siano presenti (sono). Ho cambiato il padding per essere _qui, in quanto dimostra che funziona e non influisce sul conteggio dei byte.

Esempi in esecuzione in Swish:

Casi test

Approccio, fondamentalmente la prima cosa che potrei fare lavorare, e senza dubbio un abile utente Prolog potrebbe accorciarlo molto:

  • Data una stringa di lunghezza L, l'output avrà linee L e ogni riga sarà lunga L caratteri, quindi 'L' appare molto. Conto alla rovescia da L a 0 per il numero di linee, L per la lunghezza della sottostringa per ogni linea.
  • Crea una stringa di riempimento di L spazi (caratteri di sottolineatura) lunghi, aggiungila ad entrambe le estremità della stringa di input, perché è una lunghezza semplice che sicuramente sarà abbastanza riempimento.
  • Calcola uno scostamento iniziale in questa stringa di tre lunghezze e ricorre, generando una sottostringa ogni volta, in un elenco di risultati.

Codice spiegato e commentato (potrebbe non essere eseguito), letto dal superacrostic()basso, quindi helper()corpo principale, quindi helper()caso base:

% helper function recursive base case, 
% matches when counter is 0, other input has any values, and empty list 'output'.
helper(_,0,_,_,[]). 



% helper function recursively generates substrings
% matching a padded input Text, a line Counter
% a substring starting Offset, a line Length,
% and an output list with a Head and a Tail
helper(Text, Counter, Offset, LineLength, [Head|Tail]):-

    sub_string(Text, Offset, LineLength, _, Head),    % The list Head matches
                                                      % a substring of Text starting 
                                                      % from Offset, of LineLength chars 
                                                      % and

    NextCounter is Counter-1,                         % decrement the Counter

    NextOffset is Offset+1,                           % increment the offset

    helper(Text, NextCounter, NextOffset, LineLength, Tail).  % Recurse for list Tail



% Result is a superacrostic for an input string Text, if
superacrostic(Text, Result):-
    string_length(Text, Length),                   % Length is length of input, 
                                                   % Text = 'ABXCD', Length = 5
                                                   % and

    findall('_',between(1,Length,_),PaddingList),  % PaddingList is a list of padding
                                                   % chars Length items long, 
                                                   % ['_', '_', '_', '_', '_']
                                                   % and

    string_chars(PaddingString, PaddingChars),     % PaddingString is the string from 
                                                   % joining up that list of chars
                                                   % '_____'
                                                   % and

    string_concat(PaddingString, Text, Temp),      % Temp is Text input with a
                                                   % padding prefix
                                                   % Temp = '_____ABXCD'
                                                   % and

    string_concat(Temp, PaddingString, PaddedText), % PaddedText is Temp with 
                                                    % a padded suffix
                                                    % Temp = '_____ABXCD_____'
                                                    % and


    S is Length - ((Length - 1) / 2),              % Starting offset S for the substring
                                                   % is just past the padding,
                                                   % then half the input length back
                                                   % '_____ABXCD_____'
                                                   %     |
                                                   % to start the first line,
                                                   % and


    helper(PaddedText, Length, S, Length, Result). % Result is the list generated from 
                                                   % the helper function, 

    % to recurse Length times for that many output rows, S starting offset, 
    % Length linelength, and Result 'output'.

2

05AB1E , 11 byte

g;úIvDIg£,À

Provalo online!

Spiegazione

g;ú           # prepend len(input)/2 spaces to input
   Iv         # for each char of input do
     D        # duplicate current string
      Ig£     # take the first len(input) chars
         ,    # print
          À   # rotate the string to the left

2

JavaScript (ES6), 75 byte

f=(s,k=1,l=s.length)=>k>l?'':(' '.repeat(l)+s).substr(l/2+k,l)+`
`+f(s,k+1)

console.log(f("World"))


72 byte . O 70 byte se vuoi andare con ES8, come ho fatto io.
Shaggy,

2

APL (Dyalog Unicode) , 10 caratteri = 22 byte

{⊢⌺(≢⍵)⊢⍵}

Provalo online!

{... } funzione anonima in cui l'argomento è rappresentato da

 fornire l'area coperta quando

⌺(... ) facendo scorrere uno stencil di dimensioni

   lunghezza di

   l'argomento

 su

 l'argomento

Il modo in cui funziona è quello di lasciare che ogni carattere formi il centro di una stringa con la stessa lunghezza dell'input, riempiendo a sinistra oa destra secondo necessità. Prendi ad esempio ABXCD:

La stringa ha cinque caratteri, quindi lo stencil avrà una "apertura" larga cinque caratteri.

┌──↓──┐     apertura stencil con pennarello mezzo
│ ABX│CD   puoi Aessere nel mezzo
 │ ABXC│D   poi B
  │ABXCD|   ecc
  A|BXCD | 
  AB|XCD  |
    └──↑──┘ posizione finale stencil



2

JavaScript (ES8), 66 63 62 byte

Restituisce un array.

s=>[...s].map((_,x)=>s.padStart(l*1.5).substr(x,l),l=s.length)

Provalo

o.innerText=(f=
s=>[...s].map((_,x)=>s.padStart(l*1.5).substr(x,l),l=s.length)
)(i.value="Pneumonoultramicroscopicsilicovolcanoconiosis").join`\n`;oninput=_=>o.innerText=f(i.value).join`\n`
<input id=i><pre id=o>


Spiegazione

s=>

Funzione anonima che accetta la stringa come argomento tramite parametro s.

[...s]

Dividi la stringa in una matrice di singoli caratteri.

l=s.length

Ottieni la lunghezza della stringa e assegnala alla variabile l.

.map((_,x)=>                                        )

Mappa sull'array, passando ciascun elemento attraverso una funzione, dove si xtrova l'indice dell'elemento corrente.

s.padStart(l*1.5)

Per ogni elemento, restituisci la stringa originale con spazi anteposti fino a quando la sua lunghezza è 1,5 volte quella della sua lunghezza originale.

.substr(x,l)

Ottieni la sottostringa di lunghezza a lpartire dall'indice dell'elemento corrente.


2

V , 14 , 11 byte

òlÙxHÄ$x>>ê

Provalo online!

3 byte salvati grazie a @nmjmcman!

hexdump:

00000000: f26c d978 48c4 2478 3e3e ea              .l.xH.$x>>.

Approccio originale (18 byte):

ø..
Duu@"ñLÙxHÄ$x>

Spiegazione:

ò           " Recursively:
 l          "   Move one char to the right (this will break the loop if we move too far
  Ù         "   Duplicate this line down
   x        "   Delete the first character on this line
    H       "   Move to the first line
     Ä      "   Duplicate this line up
      $     "   Move to the end of this line
       x    "   And delete a character
        >>  "   Put one space at the beginning of this line
          ê "   And move to this column on the last line
            " (implicit) ò, end the loop.

Salva un paio di byte: provalo online!
nmjcman101,

@ nmjcman101 Ah, è geniale! Mi sono completamente dimenticato ê. Grazie :)
DJMcMayhem

2

PowerShell Core , 68 byte

0..($L=($a="$args").Length-1)|%{-join(' '*($L/2)+$a)[($_..($_+$L))]}

Provalo online!

Spiegazione non golfata

# Input string ABXCD
# -> indexes  0,1,2,3,4  string indexing and num of output lines.
# -> Pad with half-len of spaces __ABXCD.
# -> sliding window array of chars:
# __ABXCD
# |    |       0..4
#  |    |      1..5
#   |    |     2..6
#    |    |    3..7   (selecting indexes past the end returns $nulls, no error)
#     |    |   4..8

# joining those chars into a line


$Text = "$args"                            # script args array to string.
$L    = $Text.Length - 1                   # useful number

$Offsets = 0..$L                           # range array 0,1,2,3,.. to last offset

$Offsets | ForEach-Object {                # Offsets doubles as number of output lines

    $LinePadding = ' ' * ($L / 2)          # lead padding string __
    $PaddedText  = $LinePadding + $Text    # -> __ABXCD

    $Chars = $_..($_+$L)                   # windows 0..4, then 1..5, then 2..6, etc.
    $Line  = $PaddedText[$Chars]           #_,_,A,B,X then _,A,B,X,C then A,B,X,C,D etc.

    -join $Line                            # __ABX  then _ABXC then ABXCD etc.

}

1
Ti interessa ungolf l'adesione a [($_..($_+$L))]?
radice

@root risposta breve, il (non va con il join, sta facendo -join ($Padding + $Text)[0,1,2,3,4]selezionare diversi caratteri da una stringa imbottita per una linea di output e unendo quelli in una stringa per essere un modo più breve di fare .SubString(). e sta generando l'imbottitura sul posto e l'intervallo di caratteri sul posto. Spiegazione ungolf completa aggiunta alla mia risposta.
TessellatingHeckler,

2

Japt , 19 17 14 byte

5 byte salvati grazie a @ETHproductions e @Shaggy

¬£iSp½*Ul¹tYUl

Provalo online! -Rflag aggiunto per unirsi a newline (scopi di visibilità)

Spiegazione

¬£iSp½*Ul¹tYUl
                U = Implicit input
¬               Split the input into an array of chars
 £              Map; At each char:
  i               Insert:
   S                Space " "
    p               repeated(
     ½*Ul           .5 * U.length times 
         ¹          )
          t        Substring(
           Y         Index,
            Ul       U.length) 

1
Dovrebbe esserci un modo molto più breve per generare Sp½*Ul, ma non credo che ci sia un atm ... A proposito, di solito puoi cambiare sXX+Yin tXY( s == .slice, t == .substr)
ETHproductions

@ETHproductions Oh sì, grazie!
Oliver,


Oppure, visto che è consentito restituire un array, 14 byte .
Shaggy,

1

Carbone , 26 byte

A⁺¹÷Lθ²δFδ⟦✂θι⁺ιδ⟧F∕θ²C¹±¹

Provalo online! Il collegamento è alla versione dettagliata del codice.


1

Gelatina , 11 byte

LH⁶ẋ;ṫJḣ€LY

Provalo online!

Come funziona

LH⁶ẋ;ṫJḣ€LY   "ABXCD"
L             5
 H            2.5
  ⁶ẋ          "  "
    ;         "  ABXCD"
     ṫJ       ["  ABXCD"
               " ABXCD"
               "ABXCD"
               "BXCD"
               "XCD]
        ḣ€L   ["  ABX"
               " ABXC"
               "ABXCD"
               "BXCD"
               "XCD]
           Y  "  ABX
                ABXC
               ABXCD
               BXCD
               XCD"

1

QBIC , 32 byte

_L;|A=space$(a'\`2)+A[a|?_sA,b,a    

Amico, è tempo che io aggiunga space$ a QBIC ...

Spiegazione

  ;             Read a cmd line parameter as A$
_L |            And take its length as 'a'
A=space$        Set A$ to a number of spaces
(a'\`2)           equal to its own length halved
+A                prepended to itself
[a|             FOR b= 1 to the length of A$
?_sA,b,a        Print a substring of our space-padded A$, starting at the b'th character, running for a chars

Esecuzione del campione

Command line: acknowledgement
       acknowle
      acknowled
     acknowledg
    acknowledge
   acknowledgem
  acknowledgeme
 acknowledgemen
acknowledgement
cknowledgement
knowledgement
nowledgement
owledgement
wledgement
ledgement
edgement

1

Mathematica, 88 byte

T=Table;Column@Reverse@T[T[" ",i]<>StringDrop[s=#,-i],{i,d=-⌊StringLength@s/2⌋,-d}]&

1

Haskell , 86 70 byte

Questo è (ancora) troppo lungo, ma grazie @bartavelle per avermi ricordato che è anche accettabile produrre un elenco di stringhe!

f s|m<-div(length s)2=take(2*m+1).(`drop`((*>)s" "++s))<$>[m+1..3*m+1]

Provalo online!


Ho potuto raggiungere solo 82: provalo online!
bartavelle,

@bartavelle Non sembra giusto. La tua parte destra non è tritata.
Adám,

Sì, ho introdotto un bug! Puoi guadagnare un po 'abbandonando il tuo concat: provalo online!
bartavelle,

E con il taglio è 84, rendendo migliore il tuo approccio! Provalo online!
bartavelle,

E puoi risparmiare molto di più, poiché non è necessario restituire una singola stringa, anche gli elenchi di stringhe sono OK!
bartavelle,


1

PowerShell , 133 119 byte

$a="$args";$L=$a.Length;$m=($L+1)/2;$s=" "*($m-1)+$a+" "*($m-1);for($h=0;$h-lt$L;$h++){$r="";0..$L|%{$r+=$s[$_+$h]};$r}

Provalo online!

Ungolfed

$a="$args"
$L=$a.Length                        # the length of the input
$m=($L + 1) / 2                     # the midpoint of the input
$s=" " * ($m-1) + $a + " " * ($m-1) # create a string using the input and padded on both sides with spaces

for($h=0;$h -lt $L;$h++) {          # the height, matching the length of the input
    $r=""                           # init/reset the output string

    0..$L | % {                     # number range to represent each character in the string
        $r+=$s[$_+$h]               # append the output string with the next character
    }

    $r                              # write the output
}

1
Bella risposta! Benvenuti nel sito. :)
DJMcMayhem

1

Python 2 ,76 74 73 byte

-1 grazie a @FelipeNardiBatista

Certo, non breve come l'altra risposta di Python, ma vale la pena provare un metodo completamente diverso:

n=input();x=len(n)
for i in range(x):print((2*x-~i)*' '+n)[x+x/2:2*x+x/2]

Provalo online! (con la versione da 74 byte)

Questo prima genera la stringa completa, quindi la divide per adattarla al quadrato.


Spiegazione

n = input (); - accetta l'input e lo assegna a una variabile n
          x = len (n) - assegna la lunghezza dell'input a una variabile x
per i nell'intervallo (x): - scorre nell'intervallo 0 ... x, con una variabile i
                   stampa - genera il risultato
                         ((2 * xi-1) * '' + n) - crea la stringa "diamante"
                                          [x + x / 2: 2 * x + x / 2]: ritaglia la stringa per adattarla alla casella

(2*x+~i)per salvare un byte
Felipe Nardi Batista

@FelipeNardiBatista Grazie.

1

J , 19 byte

|.!.' '"{~2%~#\-#\.

Provalo online!

Spiegazione

|.!.' '"{~2%~#\-#\.  Input: string S
             #\      Length of each prefix of S, [1, 2, ..., len(S)]
                #\.  Length of each suffix of S, [len(s), ..., 2, 1]
               -     Subtract elementwise
          2%~        Divide by 2
                     We now have a range [(1-len(S))/2, ..., -1, 0, 1, ..., (len(S)-1)/2]
       "{~           Use each value to operate on S
|.!.' '                Perform a shift while replacing characters with ' '

Funziona con ''come sostituto.
FrownyFrog,

0

C # (.NET Core) , 101 byte

(a)=>{int L=a.Length,l=L/2;for(;l-->0;)a=" "+a+" ";for(;++l<L;)Console.WriteLine(a.Substring(l,L));};

Fondamentalmente la risposta di KevinCruijssen. Salva 2 byte perché string.Lengthnon è necessario () e altri 2 byte perché il secondo argomento di string.Substring()è lunghezza anziché fine indice, ma quindi perde 2 byte perché Console.WriteLine()è più lungo. Avevo un'implementazione più ingenua, ma era circa il doppio del tempo, quindi ...


0

Excel VBA, 68 byte

golfed

Funzione di finestra immediata VBE anonima che accetta input dalla cella [A1]e output nella finestra immediata di VBE

l=[Len(A1)]:For i=Int(-l/2)+2To l/2+1:?Mid(Space(l-i)&[A1],l,l):Next

Ungolfed

Sub C(ByVal s As String)
    Let l = Len(s)
    For i = Int(-l / 2) + 2 To l / 2 + 1 Step 1
        Debug.Print Mid(Space(l - i) & s, l, l)
    Next i
End Sub

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.