Jaque mate (también conocido como el problema urinario)


35

Mi maestro de Precalc tiene uno de sus problemas favoritos que inventó (o más probablemente robó inspirado por xkcd ) que involucra una fila de nurinarios. "Jaque mate" es una situación en la que cada urinario ya está ocupado O tiene un urinario ocupado junto a ellos. Por ejemplo, si una persona es un X, entonces

X-X--X

se considera jaque mate. Tenga en cuenta que una persona no puede ocupar un orinal junto a un orinal ya ocupado.

Tarea

Su programa tomará un número stdin, argumentos de línea de comando o un argumento de función. Luego, su programa imprimirá o devolverá la cantidad de formas en que el jaque mate puede ocurrir con la cantidad ingresada de urinarios.

Ejemplos

0 -> 1(el caso nulo cuenta como jaque mate)
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-)
...

Tanteo

El programa más pequeño en bytes gana.




12
El caso n = 0 debería ser 1. Hay exactamente una configuración que es jaque mate, y esa es ''. Esto es lo mismo que con factorial y permutaciones, 0! = 1, porque hay exactamente 1 forma de organizar 0 elementos.
orlp


19
Ningún baño es una situación de jaque mate. : D
Tito

Respuestas:


20

Oasis , 5 bytes

Código

cd+2V

Versión extendida

cd+211

Explicación

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

Pruébalo en línea!


77
Esta es una respuesta extraña, el lenguaje fue creado hace aproximadamente un mes sin la documentación adecuada en el repositorio ....

2
@tuskiomi Tiene un documento, eninfo.txt
TuxCrafting

66
@ TùxCräftîñg seguro, si quieres ser técnico. Podría dibujar un caballo y llamarlo documentación para mi proyecto de programación. eso no lo hace útil o decisivo.

1
@tuskiomi info.txtes útil, contiene una documentación para cada comando de Oasis
TuxCrafting

8
@tuskiomi Ese es el resultado de la dilación y la pereza. Trataré de agregar una documentación concisa sobre cómo funciona el lenguaje actual.
Adnan

12

Java 7, 65 42 bytes

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

La secuencia solo agrega elementos anteriores para obtener nuevos. Punta de sombrero para orlp y Rod para este método más corto;)

Antiguo:

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

Después del quinto elemento, la brecha en la secuencia aumenta en el elemento cinco anterior.


Si u = 3, entonces su función devuelve 1, pero los ejemplos muestran que debería ser 2.
Poke

¡Uy! Estaba usando mi ffunción desde el otro fragmento en lugar de recurrir. Estúpido, arreglando ...
Geobits

1
¿No puede ser esa última parte ( u>0?u:1;) 1;?
Conor O'Brien

2
@ Jordania Si hay cero urinarios, entonces "cada urinario ya está ocupado" en la única configuración posible. Creo que el caso de prueba que se muestra en la pregunta es incorrecto.
Geobits

1
Puede reemplazar u>0?u:1;)por 1;si cambia la primera comparación a u>1, luego en u = 2 la salida será g (0) + g (-1), que será 2
Rod

9

Python 2, 42 40 39 35 bytes

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

Generando los conjuntos reales:

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

Ruby, 58 34 bytes

Muy inspirado por la respuesta original de Java de Geobits.

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

Véalo en repl.it: https://repl.it/Dedh/1

Primer intento

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

Véalo en repl.it: https://repl.it/Dedh


6

Python, 33 bytes

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

Utiliza los casos base desplazados f(-1) = f(0) = f(1) = 1. Si Truepudiera usarse para 1, no necesitaríamos 3 bytes para el +().


6

J, 31 27 23 bytes

¡Guardado 4 bytes gracias a millas!

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

Una explicación vendrá pronto.

Vieja solución

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

Esta es una agenda. El LHS es un gerundio compuesto por dos verbos: >.1&^y -&3+&$:-&2. El primero se usa si la condición ( 2&<) falla. Eso significa que la bifurcación >.1&^se activa sobre el argumento. Observar:

   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

Aquí, >.toma el máximo de dos valores. Por lo tanto, produce 1, 1 y 2 como los términos iniciales.

El segundo verbo en el gerundio es un tenedor:

-&3 +&$: -&2

Los dientes izquierdo y derecho se aplican al verbo, restando 3 y 2 respectivamente; entonces el verbo del medio se llama con argumentos izquierdo y derecho iguales a esos. $:llama al verbo en cada argumento y +agrega esos dos. Básicamente es equivalente a($: arg - 3) + ($: arg - 2)

Casos de prueba

   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 bytes

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

Pruébalo en línea! O revise todos los casos de prueba .

Explicación

¡Dos convoluciones! ¡Hurra!

Esto crea una matriz, digamos A, donde cada configuración posible es una fila. 1en esta matriz representa una posición ocupada. Por ejemplo, para la entrada, 4la matriz A es

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

El código entonces involucra la matriz A con [1 1 1]. Esto proporciona una matriz B. Las posiciones ocupadas y las vecinas de las posiciones ocupadas en A dan un resultado distinto de cero en la matriz B:

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

Entonces, la primera condición para que una configuración sea un jaque mate es que B no contiene ceros en esa fila. Esto significa que en esa fila de A no había puestos vacíos, o había algunos pero eran vecinos de puestos ocupados.

Necesitamos una segunda condición. Por ejemplo, la última fila cumple la condición anterior, pero no es parte de la solución porque, para empezar, la configuración no era válida. Una configuración válida no puede tener dos posiciones ocupadas vecinas, es decir, no puede tener dos contiguas 1en A. De manera equivalente, no puede tener dos valores contiguos en B superiores 1. Por lo tanto, podemos detectar esto haciendo girar B con [1 1]y verificando que en la matriz resultante, C,

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

ningún valor en esa fila excede 3. El resultado final es el número de configuraciones que cumplen las dos condiciones.

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 bytes

+3 para n=1; +9 para $argv, -1-3 golf
-20: noté que no tengo para las combinaciones, sino solo su cuenta

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

corre con -r

bucle de 2 ** n-1 a 0:

  • comprobar representación binaria de n dígitos para 11, 000, 00al principio o al final, o una sola0
  • si no coincide, aumenta el resultado

resultado de impresión

mismo tamaño, expresiones regulares un poco más simples

for($i=1<<$n=$argv[1];--$i;)$r+=!preg_match("#11|^00|00[,0]#",sprintf("%0{$n}b,",$i));echo$r;
  • bucle de 2 ** n-1 a 1 (en lugar de 0)
  • verificar la representación binaria para 11, 00al principio o al final, o000
  • no imprime nada para n = 0

PHP, 82 bytes

La respuesta de Arnauld portó y jugó golf:

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

no imprime nada para n = 0


agregue 3 bytes para el nuevo n=0: inserte ?:1antes de la final;
Titus

4

Jalea , 11 bytes

,’fR_2߀So1

Pruébalo en línea! o verificar todos los casos de prueba .

Cómo funciona

,’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
¿Como funciona esto? ¿Utiliza la fórmula recursiva, o alguna otra cosa?
Conor O'Brien

@ ConorO'Brien Sí, utiliza la fórmula recursiva. He añadido una explicación.
Dennis

4

JavaScript (ES6) / Recursivo, 30 27 bytes

Editar: guardado 3 bytes gracias 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) / No recursivo 90 77 bytes

Editar: guardado 13 bytes gracias a Conor O'Brien y 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
I think ((i|r|l)&(k-1)) can become ((i|r|l)&k-1), or even ((i|r|l)&~-k)
Conor O'Brien

one byte: i<<1 -> i*2 or i+i
Titus

1
You can use one variable for l and r, saving 6 bytes: !(i&(x=i>>1|i+i))&&((i|x)&(k-1))==k-1; and if you can insert ,k-- somewhere, you can replace k-1 with k to save parens.
Titus

&(k-1) needs no parens anyway; but you can use &~k instead.
Titus

1
i'm just gonna leave this here: f=n=>n<3?n||1:f(n-2)+f(n-3)
Shaun H

3

Mathematica, 35 bytes

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

Defines a function a. Takes an integer as input and returns an integer as output. Simple recursive solution.


3

AnyDice, 51 bytes

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

There should be more AnyDice answers around here.

My solution defines a recursive function that calculates a(n)=a(n-2)+a(n-3). It returns a(0)=a(1)=1 and a(2)=2 using some integer division magic.

Try it online

Nota: el resultado puede parecer extraño, y eso se debe a que generalmente se usa para generar probabilidades de dados. Solo mira el número a la izquierda del gráfico de barras.


3

Perl, 35 34 bytes

Incluye +1 para -p

Dar entrada sobre STDIN

checkmate.pl <<< 8

checkmate.pl:

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

Una fórmula secreta recientemente desarrollada. Ripple actualiza 3 variables de estado sin la necesidad de asignaciones paralelas.

Es igualmente corto (pero mucho más lento y requiere mucha más memoria) para resolver el problema original:

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

pero eso no funciona para 0


2

JavaScript (ES6), 62 bytes

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

Esta es la primera vez que necesito dos nombres de variables ficticias. Una versión recursiva probablemente sería más corta, pero realmente me gusta reduce... Editar: Encontré una solución, también 62 bytes, que solo tiene una variable ficticia:

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

2

Jalea , 19 bytes

La solución recursiva es probablemente más corta ...

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

Véalo en TryItOnline
O vea la serie para n = [0, 99], también en TryItOnline

¿Cómo?

Devuelve el n+3número de Padovan contando combinaciones

Ḥ⁹_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 bytes

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

Necesita que la entrada esté presente en la pila al inicio del programa, por lo que +2 bytes para el -vindicador. Pruébalo en línea!

La primera línea inicializa la pila 1 1 2 n, donde nestá el número de entrada. La segunda línea, que va hacia atrás, verifica que nsea ​​mayor que 1. Si es así, nse reduce y el siguiente elemento en la secuencia se genera de la siguiente manera:

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 línea final genera el número en la parte inferior de la pila, que es el elemento requerido en la secuencia.


2

CJam , 20 bytes

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

Pruébalo en línea!

Explicación

Esto utiliza la relación de recurrencia que se muestra en la página 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 bytes

XXXIGX@DŠ0@+

Explicación

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

Pruébalo en línea!


1

FRACTRAN, 104 93 bytes

La entrada es 11**n*29y la salida es 29**checkmate(n).

Esto es principalmente por diversión, especialmente porque actualmente estoy siendo superado por Python, JS y Java. Sin embargo, el mismo número de bytes que PHP: D Se aceptan sugerencias de golf.

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

En realidad, 25 bytes

Esto parece un poco largo para una f(n) = f(n-2) + f(n-3)relación de recurrencia simple . Sugerencias de golf bienvenidas. Pruébalo en línea!

╗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

Actualmente , 18 bytes

Este es un puerto de la respuesta más larga de Jelly de Dennis. Sugerencias de golf bienvenidas. Pruébalo en línea!

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.



Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.