Equilibre um conjunto de pesos em uma gangorra

32

Lei de Equilíbrio

visão global

Dada uma entrada de 3 números inteiros positivos de um dígito, representando um conjunto de pesos, produz uma representação ASCII de uma gangorra com os pesos colocados nela, para que fique em equilíbrio em torno de um pivô central, levando em consideração os efeitos da alavanca.

Cada número tem um peso igual ao seu valor. O torque de cada número é o peso multiplicado pela distância do centro em caracteres. Para a gangorra estar em equilíbrio, o torque soma dos pesos do lado esquerdo da gangorra deve ser igual a daqueles à direita, como este .

Entrada

3 números inteiros no intervalo de 1 a 9. Você pode inserir os números inteiros, no entanto, é conveniente, por exemplo, uma tupla, 3 valores separados por vírgula etc. No entanto, seu programa deve ser capaz de lidar com números introduzidos em qualquer ordem (ou seja, sem assumir que os valores serão classificados). Números duplicados podem ser introduzidos (por exemplo, 2,3,2).

As entradas sempre permitirão matematicamente uma saída válida, caso contrário, a entrada não é válida.

Saída

A saída deve ser uma representação ASCII de 2 linhas da gangorra com os pesos colocados nela. Na primeira linha estão os dígitos, espaçados para equilibrá-los na gangorra.

Os números não podem ser colocados no centro da balança, onde a distância e, portanto, o torque seriam zero. As distâncias válidas do centro variam de 1 a 10 caracteres, inclusive à esquerda ou direita do pivô.

Nos espaços desocupados pelos números, há 18 caracteres sublinhados (um sublinhado central e 10 de cada lado, menos as 3 posições ocupadas pelos números). Na última linha, há um caractere de cursor único alinhado com o centro da escala, representando o pivô.

Exemplos

Entrada:

4,7,2

Saída:

________7___42_______
          ^

7 * 2 = 4 * 2 + 2 * 3

Os números podem ser impressos em ambos os lados, por exemplo, isso também seria válido:

_______24___7________
          ^

2 * 3 + 4 * 2 = 7 * 2

Os números podem ser colocados em qualquer lugar da balança, desde que equilibrados, por exemplo:

Entrada:

3,1,5

Saída:

_____5________1__3___
          ^

5 * 5 = 1 * 4 + 3 * 7

ou

____5________1_____3_
          ^

5 * 6 = 1 * 3 + 3 * 9

ou

____5___________1_3__
          ^

5 * 6 = 1 * 6 + 3 * 8

etc

Seu programa precisa apenas produzir uma das saídas válidas. Não é necessário gerar um erro se a entrada não for válida.

Notas

  • Isso é então o programa mais curto em bytes vence
  • O programa pode ser autônomo ou uma função que aceita os números como entrada e retorna uma string.
  • Trailing newline e espaço em branco na última linha é opcional
  • Se você não sabe o que é uma gangorra , ela também é conhecida como gangorra ou gangorra.
samgak
fonte
Aqui está uma pasta mostrando entradas e soluções válidas (com alguma duplicação)
samgak
11
Um excelente primeiro desafio! Um problema interessante e uma especificação completa.
Xnor
2
Algoritmicamente, dado um vetor numerado inteiro, isso solicita que você encontre um vetor ortogonal numerado inteiro com todas as entradas diferentes.
haskeller orgulhoso

Respostas:

13

CJam, 40 39 38 bytes

q~21Ue]e!{21,Af-Aest.*:+!}=0'_erNAS*'^

Experimente online.

Como funciona

q~                                     e# Read and evaluate the input.
  21Ue]                                e# Append zeroes to achieve a length of 21.
       e!                              e# Push all unique permutations.
         {               }=            e# Find the first permutation such that:
          21,                          e#  Push [0 ... 20].
             Af-                       e#  Subtract 10 from each.
                Aest                   e#  Replace the element at index 10 with the
                                       e#  current time (ms since epoch) to push
                                       e#  [-10 ... -1 <big number> 1 ... 10].
                    .*                 e#  Multiply each number of the permutation
                                       e#  by the corresponding distance.
                      :+               e#  Add the products.
                                       e#  The timestamp makes sure that this sum
                                       e#  is non-zero for a non-zero element in
                                       e#  the middle of the permutation.    
                        !              e#  Push the logical NOT of the sum.
                           0'_er       e# Replace zeroes with underscores.
                                NAS*'^ e# Push a linefeed, ten spaces and a caret.
Dennis
fonte
5

CJam, 46 44 bytes

'_21*q~K,Am3m*{___&=*Afm1$.*:+!}=.{\t}NAS*'^

Teste aqui.

Explicação

Primeiro, uma observação: nunca precisamos colocar dois dígitos nas extremidades da gangorra. Sempre que for uma solução válida, há pelo menos uma outra solução válida (de acordo com a pasta no comentário no desafio).

'_21*   e# Push a string of 21 underscores.
q~      e# Read and eval input.
K,      e# Push the array [0 1 .. 19 20]
Am      e# Remove the 10. This is now an array of all valid positions on the seesaw.
3m*     e# Get all 3-tuples of valid positions.
{       e# Select the first tuple for which the following block yields a truthy result.
  ___   e# Make three copies of the tuple.
  &=    e# Intersect the last two copies and check for equality with the first one.
        e# This yields 1 if all positions are distinct, and 0 otherwise.
  *     e# Repeat the original tuple that many times. That is, if the positions are
        e# distinct, leave the tuple unchanged. Otherwise, replace it with an empty array.
  Afm   e# Subtract 10 from each position to get its weight.
  1$    e# Copy the input digits.
  .*    e# Take the pairwise product of weights and digits. If the weights are empty
        e# (because they were not unique), this will just yield a list of the digits.
  :+    e# Sum the weighted digits. If the weights were not unique, this will just sum
        e# the digits and will always be positive.
  !     e# Logical NOT - give 1 if the sum was 0, or 0 otherwise.
}=
.{\t}   e# For each pair of digit and position, replace that position in the underscore
        e# string with the corresponding digit.
N       e# Push a newline.
AS*     e# Push ten spaces.
'^      e# Push a caret.
Martin Ender
fonte
5

Java, 519 414 321 bytes

static int f(int a,int b,int c){int i,j,k;for(i=-10;i<=10;i++)for(j=i+1;j<=10;j++)for(k=j+1;k<=10;k++){if(a*i+b*j+c*k==0&&i!=0&&j!=0&&k!=0){for(int q=0;q<21;q++){if(q==10+i)p(a);else if(q==10+j)p(b);else if(q==10+k)p(c);else p('_');}p("\n          ^\n");return 0;}}return 0;}static void p(Object a){System.out.print(a);}}

Minha primeira tentativa de jogar golfe.

Você pode ligar com f(a,b,c). Experimente aqui

EDIT: método de verificação izlin usado(a*i+b*j+c*k)==0

EDIT: Obrigado, J Atkin pelas sugestões de golfe.

QSilver
fonte
11
Você pode salvar alguns bytes alterando a assinatura de ppara Object ae usando-a no lugar dos outros 2 System.out.print(ln)s.
J Atkin
11
E como aé usado apenas uma vez, você pode incorporá-lo.
precisa
5

Pyth, 67 58. 53 49 bytes

Isso parece um pouco enorme para Pyth, mas eu não estou familiarizado o suficiente com o idioma para poder ficar muito menor. Sub 50 bytes, finalmente estou feliz com isso!

V.c-KrT-011Z3FY.pQIqs*VNYZjkm?}dN@YxNd\_K+*dT\^.q

A entrada é esperada como uma matriz de números inteiros, por exemplo [1,2,3]. Experimente aqui.

Explicação:

V.c-KrT-011Z3FY.pQIqs*VNYZjkm?}dN@YxNd\_K+*dT\^.q
                                                       Implicit: Q = eval(input())
     rT-011                                            Create range from 10 to -10
    K                                                  Store in K
   -       Z                                           Drop 0 from the above
V.c         3                                          For N in (combinations of the above of size 3)
             FY.pQ                                     For Y in (permutations of input)
                     *VNY                              Multiply each element in N by the corresponding element in Y
                    s                                  Take the sum
                  Iq     Z                             If it's equal to zero:
                            m           K              For d in K (K = [10, ..., -10])
                             ?}dN                      Is d in N?
                                 @YxNd                 If so, get corresponding value from Y
                                      \_               Otherwise, get '_'
                          jk                           Join the resulting array into a string (implicit print)
                                         +*dT\^        Join 10 spaces and '^', implicit print
                                               .q      Break all loops and exit

E, finalmente, alguns exemplos de entradas e saídas:

[1,1,1] ->
1__________1_______1_
          ^

[2,9,5] ->
2____5_________9_____
          ^

[9,8,5] ->
5____8______________9
          ^
Sok
fonte
4

C - 237 228 bytes

i,j,k;f(a,b,c){char o[]="_____________________\n          ^";for(i=-10;i<9;i+=i+1?1:2){for(j=i+1;j<11;j+=j+1?1:2){for(k=j+1;k<11;k+=k+1?1:2){if((a*i+b*j+c*k)==0){o[i+10]=a+48;o[j+10]=b+48;o[k+10]=c+48;printf("%s",o);return;}}}}}

Você pode ligar com f(a,b,c).

Experimente aqui .

Exemplo de saídas:

f(4,7,2):
4_____________7_2____
          ^         

f(3,1,5)
3____1___________5___
          ^       
Izlin
fonte
3

Python 2.7 235 226 219 bytes

def s(n,p=__import__("itertools").permutations):
 l=["_"]*21
 for p,q in[[(a,x+10),(b,y+10),(c,10-z)]for a,b,c in p(n,3)for x,y,z in p(range(1,11),3)if x!=y and a*x+b*y==c*z][0]:l[q]=`p`
 return`l`[2::5]+"\n"+" "*10+"^"

Testando -o com alguns exemplos básicos - (1,1,1),(1,2,1),(3,1,5),(4,7,2)resulta em:

(1, 1, 1)
_______1___11________
          ^
(1, 2, 1)
_____1_____12________
          ^
(3, 1, 5)
________5__3_____1___
          ^
(4, 7, 2)
_2_________47________
          ^

Saídas para todas as entradas possíveis coladas aqui

Kamehameha
fonte
"".join(l) -> 'l'[2::5]é um byte mais curto (substitua as aspas por backticks).
Kade
Além disso, se você estiver disposto a alterar sua abordagem de uma função para um programa, poderá reduzir isso para 222 bytes.
Kade
@samgak oops. Meu mal, pensei ter lido a pergunta corretamente. 2 mais bytes :(
Kamehameha
@ Vioz- dica impressionante. Não sabia repr. :)
Kamehameha
3

PHP, 278 bytes

Uma solução de força bruta que usa um monte de loops aninhados e alguns testes.

$p=explode(',',$argv[$i=1]);for(;$i<=10;$i++)for($j=1;$j<=10;$j++)
for($k=1;$k<=10;$k++)if($j-$k)for($l=0;$l<3;$l++){$q=array_shift($p);
if($i*$q==$j*$p[0]+$k*$p[1]){$o=str_repeat('_',21);$o[10-$i]=$q;$o[10+$j]=$p[0];
$o[10+$k]=$p[1];echo($o."\n          ^\n");}array_push($p,$q);}

Como sempre, coloque-o em um arquivo (vamos chamá-lo seesaw.php), junte-se às linhas (divida aqui para facilitar a leitura), coloque o marcador PHP ( <?php) no início do arquivo (tecnicamente, não faz parte do programa) e você ' é bom ir.

Um exemplo de execução:

$ php seesaw.php 9,2,1
_________9_2_____1___
          ^
_________9__2__1_____
          ^
_________9_1__2______
          ^
________9_____2_____1
          ^
________9______2__1__
          ^
________9_____1__2___
          ^
________9___1_____2__
          ^
_______9_________1__2
          ^
____2______9_1_______
          ^
___2_______9___1_____
          ^
__2________9_____1___
          ^
_2_________9_______1_
          ^

Ele gera e exibe todas as soluções (sem reflexos), mas não retira as duplicatas (quando os valores de entrada contêm duplicatas).

axiac
fonte
3

Julia, 154 bytes

f(a,b,c)=(x=replace(join(first(filter(p->p⋅[-10:-1,1:10]==0,permutations([a,b,c,zeros(Int,17)])))),"0","_");print(x[1:10]*"_"*x[11:20]*"\n"*" "^10*"^"))

Ungolfed + explicação:

function f(a,b,c)
    # Create a 20-element array of the input with 17 zeros
    z = [a,b,c,zeros(Int,17)]

    # Get the set of all permutations of z such that the dot product
    # of the permutation with the distances is 0
    d = filter(p -> p  [-10:-1,1:10] == 0, permutations(z))

    # Join the first element of d into a string and replace all of
    # the zeros with underscores
    x = replace(join(first(d)), "0", "_")

    # Print the output
    print(x[1:10] * "_" * x[11:20] * "\n" * " "^10 * "^")
end
Alex A.
fonte
2

C, 252 (214) bytes

Chame com a, b, c como argumentos na linha de comando.

e=48;main(_,v,x,y,z,a,b,c)char**v;{char s[]="_____________________\n          ^";x=*v[1]-e;y=*v[2]-e;z=*v[3]-e;for(a=-1;a+11;--a)for(b=-10;b-11;++b)_=a*x+b*y,!b|b==a|_%z?0:(c=-_/z,c&c<11&c>-11?s[a+10]=x+e,s[b+10]=y+e,s[c+10]=z+e,puts(s),exit(0):0);} 

Se main pode ser omitido, a contagem de bytes cai para 214 para uma função.

a,b,c;f(x,y,z){char s[]="_____________________\n          ^";for(a=-1;a+11;--a)for(b=-10;b-11;++b)!b|b==a|(a*x+b*y)%z?0:(c=-(a*x+b*y)/z,c&&c<11&&c>-11?s[a+10]=x+48,s[b+10]=y+48,s[c+10]=z+48,puts(s),b=10,a=-b:0);}

Ambos usam a mesma estratégia de colocar o primeiro peso à esquerda, depois digitalizar ao longo das possíveis posições do segundo peso e calcular o terceiro peso. Isso permite a remoção de um loop interno.

LambdaBeta
fonte