Scacco matto (noto anche come problema dell'orinatoio)


35

Il mio insegnante Precalc ha uno dei suoi problemi preferiti che ha inventato (o più probabilmente rubato ispirato da xkcd ) che coinvolge una fila di norinatoi. "Scacco matto" è una situazione in cui ogni orinatoio è già occupato O ha un orinatoio occupato accanto a loro. Ad esempio, se una persona è una X, allora

X-X--X

è considerato scacco matto. Si noti che una persona non può occupare un orinatoio accanto a un orinatoio già occupato.

Compito

Il tuo programma prenderà un numero attraverso stdin, arg della riga di comando o un argomento di funzione. Il programma quindi stamperà o restituirà il numero di modi in cui può verificarsi lo scacco matto con il numero immesso di orinatoi.

Esempi

0 -> 1(il caso nullo conta come scacco)
1 -> 1( X)
2 -> 2( X-o -X)
3 -> 2( X-Xo -X-)
4 -> 3( X-X-, -X-Xo X--X)
5 -> 4( X-X-X, X--X-, -X-X-, o -X--X)
6 -> 5( X-X-X-, X--X-X, X-X--X, -X--X-o -X-X-X)
7 -> 7( X-X-X-X, X--X-X-, -X-X--X, -X--X-X, X-X--X-, X--X--Xo -X-X-X-)
8 -> 9( -X--X--X, -X--X-X-, -X-X--X-, -X-X-X-X, X--X--X-, X--X-X-X, X-X--X-X, X-X-X--X, X-X-X-X-)
...

punteggio

Vince il programma più piccolo in byte.




12
Il caso n = 0 dovrebbe essere 1. Esiste esattamente un setup che è scacco matto, e cioè ''. Questo è lo stesso di fattoriale e permutazioni, 0! = 1, perché esiste esattamente 1 modo per disporre 0 elementi.
orlp,


19
Nessun bagno è davvero una situazione di scacco matto. : D
Tito,

Risposte:


20

Oasi , 5 byte

Codice

cd+2V

Versione estesa

cd+211

Spiegazione

1 = a(0)
1 = a(1)
2 = a(2)

a(n) = cd+
       c      # Calculate a(n - 2)
        d     # Calculate a(n - 3)
         +    # Add them up

Provalo online!


7
Questa è una risposta strana, la lingua è stata creata circa un mese fa senza una documentazione adeguata nel repository ....

2
@tuskiomi Ha un documento, ininfo.txt
TuxCrafting,

6
@TùxCräftîñg certo, se vuoi essere tecnico. Potrei disegnare un cavallo e chiamarlo documentazione per il mio progetto di programmazione. ciò non lo rende utile o decisivo.

1
@tuskiomi info.txtè utile, contiene una documentazione per ogni comando Oasis
TuxCrafting

8
@tuskiomi Questo è il risultato di procrastinazione e pigrizia. Proverò ad aggiungere una documentazione concisa su come funziona la lingua attuale oggi.
Adnan,

12

Java 7, 65 42 byte

int g(int u){return u>1?g(u-2)+g(u-3):1;}

La sequenza aggiunge solo elementi precedenti per ottenerne di nuovi. Punta del cappello a orlp e Rod per questo metodo più breve;)

Vecchio:

int f(int u){return u<6?new int[]{1,1,2,2,3,4}[u]:f(u-1)+f(u-5);}

Dopo il quinto elemento, il divario nella sequenza aumenta dell'elemento cinque precedente.


Se u = 3, la tua funzione restituisce 1 ma gli esempi mostrano che dovrebbe essere 2.
Poke

Oops! Stavo usando la mia ffunzione dall'altro frammento invece di ricorrere. Stupido, aggiustando ...
Geobits,

1
L'ultima parte ( u>0?u:1;) non può diventare 1;?
Conor O'Brien,

2
@Jordan Se non ci sono orinatoi, allora "ogni orinatoio è già occupato" nell'unica configurazione possibile. Credo che il test case mostrato nella domanda sia sbagliato.
Geobits,

1
È possibile sostituire u>0?u:1;)da 1;se si modifica il primo confronto a u>1, allora u = 2 l'uscita sarà g (0) + g (-1), che sarà 2
Rod

9

Python 2, 42 40 39 35 byte

f=lambda n:n>1and f(n-2)+f(n-3)or 1

Generazione dei set effettivi:

lambda n:["{:0{}b}".format(i,n).replace("0","-").replace("1","X")for i in range(2**n)if"11"not in"{:0{}b}".format(i*2,2+n).replace("000","11")]

8

Rubino, 58 34 byte

Fortemente ispirato dalla risposta Java originale di Geobits.

f=->n{n<3?n:n<6?n-1:f[n-1]+f[n-5]}

Guardalo su repl.it: https://repl.it/Dedh/1

Primo tentativo

->n{(1...2**n).count{|i|!("%0#{n}b"%i)[/11|^00|000|00$/]}}

Guardalo su repl.it: https://repl.it/Dedh


6

Python, 33 byte

f=lambda n:+(n<2)or f(n-2)+f(n-3)

Utilizza i casi base spostati f(-1) = f(0) = f(1) = 1. Se Truepotesse essere usato per 1, non avremmo bisogno di 3 byte per il +().


6

J, 31 27 23 byte

Risparmiato 4 byte grazie alle miglia!

0{]_&(]}.,+/@}:)1 1 2"_

Una spiegazione arriverà presto.

Vecchia soluzione

(>.1&^)`(-&3+&$:-&2)@.(2&<)

Questa è un'agenda. LHS è un gerundio composto da due verbi: >.1&^e -&3+&$:-&2. Il primo viene usato se la condizione ( 2&<) fallisce. Ciò significa che il fork >.1&^è attivato sull'argomento. Osservare:

   1 ^ 0 1 2
1 1 1
   (1&^) 0 1 2
1 1 1
   0 1 2 >. (1&^) 0 1 2
1 1 2
   (>.1&^) 0 1 2
1 1 2

Qui, >.prende il massimo di due valori. Pertanto, produce 1, 1 e 2 come termini iniziali.

Il secondo verbo nel gerundio è un fork:

-&3 +&$: -&2

I denti sinistro e destro vengono applicati al verbo, sottraendo rispettivamente 3 e 2; quindi il verbo centrale viene chiamato con argomenti left e right uguali a quelli. $:chiama il verbo su ogni argomento e +aggiunge quei due. È sostanzialmente equivalente a($: arg - 3) + ($: arg - 2)

Casi test

   f =: (>.1&^)`(-&3+&$:-&2)@.(2&<)
   f 0
1
   f 2
2
   f 4
3
   f 6
5
   f 8
9
   F =: f"0         NB. for tables
   F i.13
1 1 2 2 3 4 5 7 9 12 16 21 28
   i.13
0 1 2 3 4 5 6 7 8 9 10 11 12
   (,. F) i.13
 0  1
 1  1
 2  2
 3  2
 4  3
 5  4
 6  5
 7  7
 8  9
 9 12
10 16
11 21
12 28

4

MATL , 25 23 byte

W:qB7BZ+t!XAw3BZ+!3>a>s

Provalo online! Oppure controlla tutti i casi di test .

Spiegazione

Due convoluzioni! Sìì!

Questo crea un array, diciamo A, dove ogni possibile configurazione è una riga. 1in questo array rappresenta una posizione occupata. Ad esempio, per l'input 4l'array A è

0 0 0 0
0 0 0 1
0 0 1 0
···
1 1 1 0
1 1 1 1

Il codice quindi comprende l'array A con [1 1 1]. Questo dà una matrice B. Le posizioni occupate e i vicini di posizioni occupate in A danno un risultato diverso da zero nella matrice B:

0 0 0 0
0 0 1 1
0 1 1 1
···
2 3 2 1
2 3 3 2

Quindi la prima condizione per una configurazione di essere un scacco matto è che B non contiene zeri in quella riga. Ciò significa che in quella fila di A non c'erano posizioni vuote, o c'erano alcune ma c'erano vicini di posizioni occupate.

Abbiamo bisogno di una seconda condizione. Ad esempio, l'ultima riga soddisfa la condizione precedente, ma non fa parte della soluzione perché la configurazione non era valida all'inizio. Una configurazione valida non può avere due posizioni occupate vicine, cioè non può avere due contigue 1in A. Equivalentemente, non può avere due valori contigui in B superiore 1. Quindi possiamo rilevarlo contorcendo B con [1 1]e verificando che nell'array risultante, C,

0 0 0 0
0 1 2 1
1 2 2 1
···
5 5 3 1
5 6 5 2

nessun valore in quella riga supera 3. Il risultato finale è il numero di configurazioni che soddisfano le due condizioni.

W:q    % Range [0 1 ... n-1], where n is implicit input
B      % Convert to binary. Each number produces a row. This is array A
7B     % Push array [1 1 1] 
Z+     % 2D convolution, keeping size. Entries that are 1 or are horizontal 
       % neighbours of 1 produce a positive value. This is array B
t!     % Duplicate and transpose (rows become columns)
XA     % True for columns that contain no zeros
w      % Swap. Brings array B to top
3B     % Push array [1 1]
Z+     % 2D convolution, keeping size. Two horizontally contiguous entries
       % that exceed 1 will give a result exeeding 3. This is array C
!      % Transpose
3>     % Detect entries that exceed 3
a      % True for columns that contain at least one value that exceeds 3
>      % Element-wise greater-than comparison (logical and of first
       % condition and negated second condition)
s      % Sum (number of true values)

4

PHP, 105 113 93 byte

+3 per n=1; +9 per $argv, -1-3 golf
-20: ho notato che non ho le combinazioni, ma solo il loro conteggio

for($i=1<<$n=$argv[1];$i--;)$r+=!preg_match("#11|(0|^)0[0,]#",sprintf("%0{$n}b,",$i));echo$r;

Corri con -r

loop da 2 ** n-1 a 0:

  • controllare rappresentazione binaria n cifre 11, 000, 00all'inizio o alla fine, o una singola0
  • se nessuna corrispondenza, aumenta il risultato

risultato di stampa

stessa dimensione, regex leggermente più semplice

for($i=1<<$n=$argv[1];--$i;)$r+=!preg_match("#11|^00|00[,0]#",sprintf("%0{$n}b,",$i));echo$r;
  • loop da 2 ** n-1 a 1 (anziché 0)
  • controlla la rappresentazione binaria per 11, 00all'inizio o alla fine, oppure000
  • non stampa nulla per n = 0

PHP, 82 byte

La risposta di Arnauld trasmessa e giocata a golf:

for($i=$k=1<<$n=$argv[1];--$i;)$r+=!($i&$x=$i/2|$i*2)&&(($i|$x)&~$k)==$k-1;echo$r;

non stampa nulla per n = 0


aggiungere 3 byte per il nuovo n=0: inserire ?:1prima della finale;
Titus

4

Gelatina , 11 byte

,’fR_2߀So1

Provalo online! o verifica tutti i casi di test .

Come funziona

,’fR_2߀So1  Main link. Argument: n

 ’           Decrement; yield n - 1.
,            Pair; yield [n, n - 1].
   R         Range; yield [1, ..., n].
  f          Filter; keep the elements that are common to both lists.
             This yields [n, n - 1] if n > 1, [1] if n = 1, and [] if n < 1.
    _2       Subtract 2 from both elements, yielding [n - 2, n - 3], [-1], or [].
      ߀     Recursively call the main link for each integer in the list.
        S    Take the sum of the resulting return values.
         o1  Logical OR with 1; correct the result if n < 1.

2
Come funziona? Utilizza la formula ricorsiva o qualcos'altro?
Conor O'Brien,

@ ConorO'Brien Sì, utilizza la formula ricorsiva. Ho aggiunto una spiegazione.
Dennis,

4

JavaScript (ES6) / Ricorsivo, 30 27 byte

Modifica: salvato 3 byte grazie a Shaun H

let

f=n=>n<3?n||1:f(n-2)+f(n-3)

for(var n = 1; n < 16; n++) {
  console.log(n, f(n));
}

JavaScript (ES6) / Non ricorsivo 90 77 byte

Modifica: salvato 13 byte grazie a Conor O'Brien e Titus

let f =

n=>[...Array(k=1<<n)].map((_,i)=>r+=!(i&(x=i>>1|i+i))&&((i|x)&~k)==k-1,r=0)|r

for(var n = 1; n < 16; n++) {
  console.log(n, f(n));
}


1
Penso che ((i|r|l)&(k-1))possa diventare ((i|r|l)&k-1), o addirittura((i|r|l)&~-k)
Conor O'Brien il

un byte: i<<1-> i*2oi+i
Tito

1
È possibile utilizzare una variabile per L e R, risparmiando 6 byte: !(i&(x=i>>1|i+i))&&((i|x)&(k-1))==k-1; e se è possibile inserire ,k--da qualche parte, è possibile sostituire k-1con kper salvare le parentesi.
Tito,

&(k-1)non ha bisogno di genitori comunque; ma puoi usare &~kinvece.
Tito,

1
lo lascerò qui:f=n=>n<3?n||1:f(n-2)+f(n-3)
Shaun H,

3

Mathematica, 35 byte

a@0=a@1=1;a@2=2;a@b_:=a[b-2]+a[b-3]

Definisce una funzione a. Accetta un numero intero come input e restituisce un numero intero come output. Semplice soluzione ricorsiva.


3

AnyDice , 51 byte

function:A{ifA<3{result:(A+2)/2}result:[A-2]+[A-3]}

Dovrebbero esserci più risposte AnyDice qui.

La mia soluzione definisce una funzione ricorsiva che calcola a(n)=a(n-2)+a(n-3). Ritorna a(0)=a(1)=1e a(2)=2usa qualche magia di divisione intera.

Provalo online

Nota: l'output può sembrare strano, e questo perché di solito è usato per generare probabilità di dadi. Basta guardare il numero a sinistra del grafico a barre.


3

Perl, 35 34 byte

Include +1 per -p

Dare input su STDIN

checkmate.pl <<< 8

checkmate.pl:

#!/usr/bin/perl -p
$\+=$b-=$.-=$\-$b*4for(++$\)x$_}{

Una formula segreta di recente sviluppo. Ripple aggiorna 3 variabili di stato senza la necessità di assegnazioni parallele.

È altrettanto breve (ma molto più lento e richiede molta più memoria) per risolvere il problema originale:

#!/usr/bin/perl -p
$_=grep!/XX|\B-\B/,glob"{X,-}"x$_

ma non funziona 0


2

JavaScript (ES6), 62 byte

n=>[1,...Array(n)].reduce(($,_,i,a)=>a[i]=i<3?i:a[i-3]+a[i-2])

Questa è la prima volta che ho bisogno di due nomi di variabili fittizie. Una versione ricorsiva sarebbe probabilmente più breve, ma mi piace molto reduce... Modifica: ho trovato una soluzione, anche 62 byte, che ha solo una variabile fittizia:

n=>[1,...Array(n)].reduce((p,_,i,a)=>a[i]=i<5?i+2>>1:a[i-5]+p)

2

Gelatina , 19 byte

La soluzione ricorsiva è probabilmente più breve ...

Ḥ⁹_c@⁸
+3µ:2R0;瀵S

Guardalo su TryItOnline
O guarda la serie n = [0, 99]anche su TryItOnline

Come?

Restituisce il n+3numero del Padovan contando le combinazioni

Ḥ⁹_c@⁸ - Link 1, binomial(k, n-2k): k, n
Ḥ      - double(2k)
 ⁹     - right argument (n)
  _    - subtract (n-2k)
     ⁸ - left argument (k)
   c@  - binomial with reversed operands (binomial(k, n-2k))

+3µ:2R0;瀵S - Main link: n
  µ       µ  - monadic chain separation
+3           - add 3 (n+3)
   :2        - integer divide by 2 ((n+3)//2)
     R       - range ([1,2,...,(n+3)//2]
      0;     - 0 concatenated with ([0,1,2,...,(n+3)//2]) - our ks
        ç€   - call previous link as a dyad for each
           S - sum

2

> <> , 25 + 2 = 27 byte

211rv
v!?:<r@+@:$r-1
>rn;

È necessario che l'input sia presente nello stack all'avvio del programma, quindi +2 byte per il -vflag. Provalo online!

La prima riga inizializza lo stack 1 1 2 n, dove si ntrova il numero di input. La seconda riga, che corre all'indietro, verifica che nsia maggiore di 1. In caso naffermativo , viene diminuito e l'elemento successivo nella sequenza viene generato come segue:

r$:@+@r              a(n-3) a(n-2) a(n-1) n

r        Reverse   - n a(n-1) a(n-2) a(n-3)
 $       Swap      - n a(n-1) a(n-3) a(n-2)
  :      Duplicate - n a(n-1) a(n-3) a(n-2) a(n-2)
   @     Rotate 3  - n a(n-1) a(n-2) a(n-3) a(n-2)
    +    Add       - n a(n-1) a(n-2) a(n)
     @   Rotate 3  - n a(n) a(n-1) a(n-2)
      r  Reverse   - a(n-2) a(n-1) a(n) n

La riga finale genera il numero sul fondo dello stack, che è l'elemento richiesto nella sequenza.


2

CJam , 20 byte

1_2_{2$2$+}ri*;;;o];

Provalo online!

Spiegazione

Questo utilizza la relazione di ricorrenza mostrata nella pagina OEIS .

1_2_                   e# Push 1, 1, 2, 2 as initial values of the sequence
           ri          e# Read input
    {     }  *         e# Repeat block that many times
     2$2$              e# Copy the second and third elements from the top
         +             e# Add them
              ;;;      e# Discard the last three elements
                 o     e# Output
                  ];   e# Discard the rest to avoid implicit display

2

05AB1E , 12 byte

XXXIGX@DŠ0@+

Spiegazione

XXX            # initialize stack as 1, 1, 1
   IG          # input-1 times do:
     X@        # get the item 2nd from bottom of the stack
       DŠ      # duplicate and push one copy down as 2nd item from bottom of the stack
         0@    # get the bottom item from the stack
           +   # add the top 2 items of the stack (previously bottom and 2nd from bottom)
               # implicitly print the top element of the stack after the loop

Provalo online!


1

FRACTRAN, 104 93 byte

L'ingresso è 11**n*29e l'uscita è 29**checkmate(n).

Questo è principalmente per divertimento, soprattutto dal momento che sono attualmente superato da Python, JS e Java. Stesso numero di byte di PHP: D Suggerimenti di golf benvenuti.

403/85 5/31 3/5 9061/87 3/41 37/3 667/74 37/23 7/37 38/91 7/19 5/77 1/7 1/17 1/2 340/121 1/11

Ungolfing

               At the start we have 11**n * 29
1/11           If n < 2, we remove the 11s and print 29**1
340/121        If n >= 2, we subtract two 11s (n-2) and add one 17, two 2s and one 5.
                 We now have 17**1 * 29**1 * 2**2 * 5.
                 These are the register for a, b, c at registers 17, 29, and 2.
                 5 is an indicator to start the first loop.
                 This loop will move a to register 13.
403/85 5/31    Remove the 17s one at a time, adds them to the 13 register.
                 5 and 31 reset the loop.
3/5            Next loop: moves b to a and adds b to a in register 13.
9061/87 3/41   Remove the 29s one at a time, adds them to the 17 and 13 registers.
                 3 and 41 reset the loop.
37/3           Next loop: moves c to b in register 29.
667/74 37/23   Remove the 2s one at a time, adds them to the 29 register.
                 37 and 23 reset the loop.
7/37           Next loop: moves a+b to c in register 2.
38/91 7/19     Remove the 13s one at a time, adds them to the 2 register.
                 7 and 19 reset the loop.
5/77           Move to the first loop if and only if we have an 11 remaining.
1/7 1/17 1/2   Remove the 7 loop indicator, and all 17s and 2s.
               Return 29**checkmate(n).

1

In realtà, 25 byte

Questo sembra un po 'lungo per una semplice f(n) = f(n-2) + f(n-3)relazione di ricorrenza. Suggerimenti di golf benvenuti. Provalo online!

╗211╜¬`);(+)`nak╜2╜2<I@E

Ungolfing

         Implicit input n.
╗        Save n to register 0.
211      Stack: 1, 1, 2. Call them a, b, c.
╜¬       Push n-2.
`...`n   Run the following function n-2 times.
  );       Rotate b to TOS and duplicate.
  (+       Rotate a to TOS and add to b.
  )        Rotate a+b to BOS. Stack: b, c, a+b
         End function.
ak       Invert the resulting stack and wrap it in a list. Stack: [b, c, a+b]
╜        Push n.
2        Push 2.
╜2<      Push 2 < n.
I        If 2<n, then 2, else n.
@E       Grab the (2 or n)th index of the stack list.
         Implicit return.

1

In realtà , 18 byte

Questa è in realtà una risposta della lunga gelatina di Dennis. Suggerimenti di golf benvenuti. Provalo online!

3+;╖½Lur⌠;τ╜-@█⌡MΣ

Ungolfing

         Implicit input n.
3+       Add 3. For readibility, m = n+3.
;╖       Duplicate and store one copy of m in register 0.
½Lu      floor(m/2) + 1.
r        Range from 0 to (floor(m/2)+1), inclusive.
⌠...⌡M   Map the following function over the range. Variable k.
  ;        Duplicate k.
  τ╜-      Push m-2k. Stack: [m-2k, k]
  @█       Swap k and m-2k and take binomial (k, m-2k).
            If m-2k > k, █ returns 0, which does not affect the sum() that follows.
         End function.
Σ        Sum the list that results from the map.
         Implicit return.



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.