Vou tombar?


36

visão global

Dada uma sequência de 3 linhas, descubra se a estrutura cai para a esquerda, se equilibra ou cai para a direita.

Estrutura de entrada

Você pode imaginar a estrutura como uma haste de metal com coisas por cima, todas equilibradas em cima de uma haste vertical.

1  7 4        a
===============
        |

A primeira linha são os itens. O peso de cada item é calculado como o valor ascii do personagem menos 32. (Caracteres abaixo de 32 não são considerados e espaços pesam 0). Lembre-se de que a força de um item na haste é seu peso vezes a distância do ponto de articulação.

A segunda linha é a haste. Cada comprimento da haste pesa 1 unidade por si só. Esta linha é exclusivamente igual a sinais ( =).

A terceira linha é o ponto de articulação. Isso pode ser colocado em qualquer lugar e é representado por vários espaços seguidos por um único |caractere pipe ( ).

Exemplos

Entrada:

=====
  |

Saída: Equilíbrio

Entrada:

=====
   |

Saída: cai para a esquerda

Entrada:

    %
=====
   |

Saída: Equilíbrio (porque %pesa o suficiente para neutralizar o peso do lado esquerdo da haste)

Entrada:

 aa
=======
   |

Saída: cai à direita (porque aa direita está mais distante do ponto de articulação)

Entrada:

1  7 4        A
===============
        |

Saída: cai para a esquerda

Entrada:

1  7 4        a
===============
        |

Saída: cai à direita (letras minúsculas são pesadas!)

Entrada:

            $ ~
===============
             |

Saída: Equilíbrio

Notas

  • O espaço em branco à direita é permitido, o espaço em branco à esquerda não é.
  • Seu programa pode produzir no formato que você quiser, desde que existam 3 saídas distintas para esquerda, balança e direita.
  • Seu programa deve aceitar o formato mostrado como entrada.


O programa pode assumir as três linhas como três seqüências separadas (por exemplo, como três argumentos para uma função ou como uma lista de três elementos)?
notjagan

@notjagan A entrada deve ser uma única sequência separada por novos caracteres de linha.
Daffy

Relacionado , possível burro.
xnor

@xnor Não é burro, porque essa pergunta lida apenas com letras maiúsculas e seu objetivo é encontrar o pivô. Minha pergunta é sobre todos os caracteres ascii> = 32, e o meu fornece o pivô e pergunta se a estrutura irá cair. Essencialmente, o inverso do que você vinculou.
Daffy

Respostas:


8

JavaScript (ES6), 116 111 108 106 bytes

-5 bytes somando via em eval(array.join`+`)vez de array.reduce().
-3 bytes por padrão, em 1vez de 32 - 31, permitindo que os parênteses sejam removidos.
-2 bytes, já que o ponto de pivô é o comprimento da última linha - 1

(s,[t,r,b]=s.split`
`)=>Math.sign(eval([...r].map((_,i)=>(t.charCodeAt(i)-31||1)*(i-b.length+1)).join`+`))

Saídas -1, 0ou 1, para a esquerda, equilibrada, ou direita, respectivamente. Acabou semelhante à resposta python de Chas Brown , então o crédito vai para lá.

Pode salvar 4 bytes se a primeira linha for preenchida para corresponder ao comprimento da haste usando
(31-t.charCodeAt(i))*(b.length+~i).

Snippet de teste

Inclui saída adicional ( Left/ Balanced/ Right) junto com o número.

f=
(s,[t,r,b]=s.split`
`)=>Math.sign(eval([...r].map((_,i)=>(t.charCodeAt(i)-31||1)*(i-b.length+1)).join`+`))
<textarea id=I rows=3 cols=20></textarea><br><button onclick="O.value=I.value?`${x=f(I.value)} (${['Left','Balanced','Right'][x+1]})`:''">Run</button> <input id=O disabled>

Outro método de 106 bytes

(s,[t,r,b]=s.split`
`)=>Math.sign(eval(r.replace(/./g,(_,i)=>"+"+(t.charCodeAt(i)-31||1)*(i-b.length+1))))

Em vez de joininserir uma matriz em +s, criamos uma sequência de números, cada um prefixado por +. A liderança +é ignorada.


1
Eu acho que (b.length+~i)pode ajudar a salvar um byte. (Eu também não entendo por que você tem a ||1.)
Neil

1
@ Neil b.length+~iretorna o negativo de i-b.length+1; isso poderia ajudar se eu pudesse negar a outra parte. Quanto ao ||1, isso foi porque eu estava assumindo que a primeira linha não estava preenchida para coincidir com o comprimento da haste, então t.charCodeAt(i)retornaria NaNalém do final da primeira linha.
Justin Mariner

Eu não tinha tentado um caso de teste não acolchoado; obrigado por explicar.
Neil

3

Python 2 , 112 110 bytes

def f(s):w,b,p=s.split('\n');return cmp(sum((ord((w+' '*-~i)[i])-31)*(i-p.find('|'))for i in range(len(b))),0)

Experimente online!

EDIT: Finalmente conseguiu eliminar o enumeratee rjustpor um mísero 2 bytes ... meh!

Toma em uma corda; saídas -1,0 ou 1 para quedas à esquerda, saldos, quedas à direita, respectivamente.

A primeira passagem em 112 bytes foi:

def f(s):w,b,p=s.split('\n');return cmp(sum((ord(c)-31)*(i-p.find('|'))for i,c in enumerate(w.rjust(len(b))),0)

(ord(c)-31)Demorei um pouco para perceber que isso realmente está incorporando o peso da própria haste junto com os itens. Muito esperto!
Daffy

1
Como por meta , você pode substituir returncom printa -1 byte (embora ele realmente não jogar bem com o código TIO atual).
notjagan

3

Haskell, 212 171 bytes (188 se receber entrada como uma sequência)

o!p=map(fst)(zip[p-0,p-1..]o)
x#p=sum(zipWith(\c w->(max(fromEnum c-32)0)*w)x(x!p))+sum(x!p)
x?c=length(takeWhile(==c)x)

Variante de 171 bytes

r a b c=signum(take(b?'=')(a++repeat ' ')#(c?' '))

Variante de 188 bytes

x%y=lines x!!y
r i=signum(take(i%1?'=')(i%0++repeat ' ')#(i%2?' '))

Explicação

o!p=map(fst)(zip[p-0,p-1..]o)        Creates weights coefs list. 
                                     o - list, p - pivot position
                                     for list "abcdf" and p=3 (pivot under 'd')
                                     outputs [3,2,1,0,-1]

x#p                                  Calculates total balance
                                     x-list of "objects" on lever, p-pivot place
  sum(zipWith                        sum of zipped lists
   (\c w->(max(fromEnum c-32)0)*w)   weight of ascii "object" times
                                     distance from pivot
    x(x!p))                          x-ascii objects, 
                                     (x!p)-distances list(weight coefs)
  +sum(x!p)                          balance of lever ("==") itself

x?c=length(takeWhile(==c)x)          length of list before non c element met
                                     used to find '|' position
                                     and length of "===" lever
                                     before right whitespaces met

r a b c=                             Sums it all up =)
                                     a-ascii objects, b-lever, c-pivot line
   signum(                           1-tips left, 0-balance, -1-tips right
     take(b?'=')(a++repeat ' ')      takes all object on lever 
                                     plus whitespaces up to length of the lever
      #                              calculate the balance
       (c?' ')                       determine place of pivot

1
Você pode usar em fromEnumvez de orde soltar o import. cpode ser simplificado para c p=max(ord p-32)0(ou com fromEnum) e, como você o está usando apenas uma vez, coloque-o em linha.
nimi

Ou você pode adicionar (Lambdabot) ao seu título, isso importa praticamente tudo o que você precisa, veja aqui .
ბიმო

1
A função cpode até ser simplificada (caracteres menores de 32 anos não são considerados) além de c p=ord p-32. Também pé basicamente length(menos 1), então p x=length x-1também funcionaria (e você pode incorporá-lo também). Também dê uma olhada na minha solução, como eu uso signum- você pode fazer r o l s = signum $ 2 * z ...quais retornos 0,1,-1para B, L, R.
ბიმო

1
Além disso, essa solução parece falhar nos casos de teste [3,4,7]e usa 3 Strings em vez de uma. (veja lines).
ბიმო

1
Aqui está uma versão com algumas dicas aplicadas (economiza 29 bytes;)).
ბიმო

2

Gelatina , 30 bytes

O_31×J_¥A+\sṪ€µ÷ḢṪ_2Ṡ
ỴṪLç@ỴḢ$

Suíte de teste

Saídas 0 para balanceado, 1 para direita e -1 para esquerda.

Como funciona

O_31×J_¥A+\sṪ€µ÷ḢṪ_2Ṡ - helper function. Arguments position of pivot and first line
O                        - char codes of first line
 _31                     - subtract 31 to get weight
    ×                    - elementwise product with:
     J_¥                 - distances from the pivot
        A                - absolute value
         +\              - cumulative sum
           s             - split to get [[...,left weight],...,[..., right + left weight]]
            Ṫ€           - last element of each sublist: [left weight, ... right weight]
              µ÷Ḣ        - get ratio of each element over left weight: ratio n indicates
                              right + left = n × left ===> right = left if n = 2
                 _2      - subtract 2: positive is right>left and negative is right<left
                   Ṡ     - return the sign of this


ỴṪLç@ỴḢ$              - main link. Argument: 3 line string.
   ç@                  - apply helper function with arguments:
Ỵ                        - split by linefeeds
 Ṫ                       - last line
  L                      - length (returns position of pivot)
       $               - and
     Ỵ                   - split by linefeeds
      Ḣ                  - first line              

2

Gelatina , 24 bytes

ṪO_31
ỴµṪLạЀṪL$×Çṣ0S€IṠ

Experimente online!

-1por cair à esquerda, 0por equilibrar, 1por cair à direita (programa completo).
[-1]por cair à esquerda, [0]por equilibrar, [1]por cair à direita (função).

A primeira linha deve ter espaços à direita, a última linha não.

Explicação (começamos com a linha inferior):

Primeiro de tudo, estamos trabalhando com linhas individuais, por isso precisamos obtê-las de alguma forma. Isso é um trabalho para . Então, precisamos tratar a \nversão -split da entrada como se fosse a entrada original; portanto, usamos µpara fazer uma cadeia monádica aplicada ao valor atual.

Agora começamos o trabalho real, e nosso primeiro trabalho seria calcular os fatores dos pesos. Essencialmente, esse é um intervalo [distância da extrema esquerda ao pivô..0..distância do pivô à extrema direita]. Primeiro, precisamos encontrar o índice baseado em 1 do pivô, que é essencialmente o comprimento da última linha sem espaços à direita. Então, exibimos a última linha (linha dinâmica) da nossa lista original com , já que não precisamos mais dela e, em seguida, aumentamos seu comprimento L. Precisamos, então, tomar o comprimento da haste, para o qual fazemos a mesma coisa na última linha (linha da haste) com ṪL$. Finalmente, para obter o alcance, mapeamos | x - y | para [1..rod length], onde x é o índice dinâmico e yé cada elemento da lista em que mapeamos. Fazemos isso usando ạЀ, onde calcula | x - y | e Ѐvaria de 1 até e incluindo o comprimento da haste. Agora teremos o alcance que queremos.

Depois disso, temos que multiplicar cada número inteiro, representando um pedaço da barra, com seu peso correspondente. Para calcular os pesos, usamos Ç, indo para a linha superior do nosso código. Pegamos a linha restante com , seus códigos com Oe, em seguida, calculamos x - 31 usando _31, x sendo cada código. Em seguida, atribuímos espaço ao peso 1 (0 + peça da haste = 1), !ao peso 2 (1 + 1) etc. Concluímos a linha superior, portanto, agora Çretornaria a lista de pesos, que multiplicamos pela correspondente inteiros representando as peças da haste com ×.

Depois disso, dividimos com ṣ0no ponto de pivô, representado por um 0 (já que qualquer peso não afeta o resultado), resultando em uma lista da forma [[1º peso, segundo peso ... peso imediatamente antes do pivô] , [peso logo após o pivô, peso após o peso anterior ... último peso]]. Essas listas representam os lados da haste, esquerda e direita. Agora somamos cada uma das listas usando S€para obter os pesos totais de cada lado e usamos Io delta, que será negativo se o lado esquerdo for mais pesado, zero se for do mesmo peso e positivo se o lado direito for mais pesado . Portanto, para retornar o resultado final usando-o adequadamente para nossa vantagem, levamos o sinal com .


2

APL (Dyalog) , 43 bytes *

{×(¯31+⎕UCS⊃⍵)+.×(⍳≢⊃⍵)-'|'⍳⍨⊃⌽⍵}⎕TC[2]∘≠⊆⊢

Experimente online!

⊆⊢ particione o argumento em execuções de caracteres que são

⎕TC[2]∘≠ diferente do 2 nd t erminal C ontrolo de caracteres (Linefeed) **

{} Aplique a seguinte função anônima na lista de strings:

⊃⌽⍵ na primeira sequência da lista invertida (ou seja, a última)

'|'⍳⍨ encontre o índice do ponto de articulação

()- Subtraia isso da seguinte lista:

  ⊃⍵ a primeira corda

   seu comprimento

   todos os indicadores disso

()+.× Soma ponderada com esses pesos e com os seguintes valores:

  ⊃⍵ a primeira corda

  ⎕UCS Os pontos de código no L niversal C haracter S et

  ¯31+ adicione trinta e um negativo (32 para o deslocamento necessário menos um para a haste)

× sinal disso


* Para 1 byte por caractere, use {×(¯31+⎕UCS↑⍵)+.×(⍳≢↑⍵)-'|'⍳⍨↑⌽⍵}⎕TC[3]∘≠⊂⊢com ⎕ML←3. Experimente online!
** ⎕TCfoi descontinuado e usado aqui apenas para fins de golfe. No código de produção, deve-se usar ⎕UCS 10.


2

Haskell (Lambdabot), 142 bytes

l=length
g[a,c,b]=splitAt(l b)$a++(' '<$[1..l c-l a])
k e=sum$zipWith((*).(-31+).ord)e[1..]
f=signum.uncurry(-).(k.drop 1.reverse***k).g.lines

Experimente online!

Versão não destruída:

-- for readability, allows reading top-down/left-right
(.>) = flip (.)

ungolfed =
     lines                                 -- separate out lines into..
  .> (\[a,b,c] ->                          -- a,b,c (first,second,third)
                                           -- ' ' pad the first line & split on pivot
       splitAt (length c) (a ++ replicate (length b - length a) ' ')
     )
  .> (weight.drop 1.reverse *** weight)    -- reverse left half, drop element above pivot & get weight for both
  .> uncurry (-)                           -- subtract right from left
  .> signum                                -- get sign

-- get ord of the character subtract 31 ('=' char from bar),
-- then multiply with scales ([1..]) and sum it all up
weight es = sum $ zipWith (ord .> subtract 31 .> (*)) es [1..]

2

Python 2 , 90 bytes

def f(s):L=len(s)/3;print cmp(sum((ord(s[i])-31)*(i-s[-L:].find('|'))for i in range(L)),0)

Espera que as linhas de entrada sejam preenchidas (com espaços) no comprimento correto. Saídas -1para quedas à esquerda , 0para equilibradas e 1para quedas à direita .

Experimente online!


94 bytes

Para +4 bytes, podemos ter uma versão que, usando um whileloop, requer linhas separadas , em vez de linhas preenchidas :

def f(s):
 i=r=0
 while''<s[i]:r+=(ord(s[i])-31)*(i-s[-3::-1].find('='));i+=1
 print cmp(r,0)

Experimente online!


1

Ruby, 543 bytes

def willittip(s)
leftw=0;
rightw=0;
arr=[];
fields=s.split("\n")
pos=fields[2].index("|")
fields[0].split("").each do |i|
arr << i.ord-32
end
arr[pos+1..-1].each_with_index do |x,y|
rightw=rightw+1
if x>0
if pos>0
rightw=rightw+x*(pos-y).abs
else
rightw=rightw+x
end
end
end
arr[0..pos-1].each_with_index do |x,y|
leftw=leftw+1
if x>0
if pos>0
leftw=leftw+x*(pos-y).abs
else
leftw=leftw+x
end
end
end
if leftw==rightw
return "Equal"
elsif leftw<rightw
return "Right"
elsif leftw>rightw
return "Left"
end
end

10
Bem-vindo ao PPCG! : D O objetivo dos desafios do código-golfe é tornar o seu código o menor possível. Você pode reduzir o tamanho do código transformando todas as variáveis ​​e nomes de funções em um único caractere e excluindo espaços em branco sempre que possível.
Daffy

1

C (gcc) , 106107 121 123 124 129 131 bytes

c,b,l,i;f(char*a){l=strlen(a)/3;for(i=b=c=0;32/a[l*2+c];++c);for(;i<l-1;b+=(a[i]-31)*(i++-c));a=b>0?2:!b;}

Retorne 0 para cair à esquerda, 1 para equilibrar e 2 para cair à direita.

Exija que as três linhas tenham o mesmo comprimento e finalize \npara determinar o comprimento da sequência.

Experimente online!


1

Mathematica, 91 92 bytes

Sign[(v=(g=ToCharacterCode)@#&@@(d=#~StringSplit~"
")-31).(Range@(l=Length)@v-l@g@Last@d)]&

A primeira linha deve ter o mesmo comprimento com a haste. A terceira linha não deve conter espaços à direita.

Retorne -1, 0, 1 para cair à esquerda, equilibrar e cair à direita.


1

C # (.NET Core) , 127 95 90 + 18 = 108 bytes

Para esta função, a primeira linha deve ser preenchida à direita, com espaços com o mesmo comprimento que a haste e a terceira linha não deve ter espaços de teste. Essas condições são permitidas (ver comentários da pergunta).

s=>s.Split('\n')[0].Select((c,i)=>(c-31)*(i-s.Split('\n')[2].Length+1)).Sum().CompareTo(0)

Experimente online!

Saídas:

-1 para a ponta esquerda
0 para o equilíbrio
1 para a ponta direita


1

Python 3, 217 bytes

Também funciona no Python 2.7

def f(s):i,b,p=s.split('\n');c=p.find('|');l=sum((ord(e)-32)*(c-i.find(e))for e in i[:c])+sum(x for x in range(1,c+1));r=sum((ord(e)-32)*i[c:].find(e)for e in i[c:])+sum(x for x in range(len(b[c:])));return(l>r)-(r>l)

Retorna 1 para o lado esquerdo, -1 para o lado direito ou zero se equilibrado.

Versão legível:

def f(s):
    i,b,p = s.split('\n')
    c = p.find('|')

    l = sum((ord(e)-32)*(c-i.find(e))for e in i[:c])+sum(x for x in range(1, c+1))
    r = sum((ord(e)-32)*i[c:].find(e)for e in i[c:])+sum(x for x in range(len(b[c:])))

    return(l>r)-(r>l)

1
Você não precisa sum([...]), você pode simplesmente tersum(...)
Mr. Xcoder

@ Daffy, isso deve ser 100% compatível com a sua especificação e com todos os exemplos de entradas. Se você concordar, informe-me para que eu possa otimizá-lo ainda mais. Obrigado.
veganaiZe

@veganaiZe Passou em todos os meus testes, parece ser bom! :)
Daffy

1
Coisas para encurtar: i[c:].find(e)pode ser i.find(e,c), use i,m,n=s.split('\n')e evite a necessidade s, return 2*(r>l) or l>rreduza drasticamente o custo do teste no final (o valor de retorno é numericamente equivalente, mas é em Truevez de 1e em Falsevez de 0) ou, na verdade, use um conjunto diferente de retorno valores e faça return (l>r)-(r>l)para retornar 1, 0 ou -1 da maneira que a cmpfunção antiga fazia.
ShadowRanger

Obrigado ShadowRanger, Sr. Xcoder e Daffy! @ShadowRanger Eu tive que ficar com o i[c:]porque o caminho mais curto causou um problema estranho de um por um para entrada de canto (tente colocar um |exatamente no meio - acima da barra).
precisa saber é o seguinte

1

PHP, 105 bytes

for([$a,$b,$c]=explode("
",$argn);$b[$i];)$w+=(strpos($c,"|")-$i++)*8*(max(1,ord($a[$i])-31));echo$w<=>0;

imprime -1/ 0/ 1para a esquerda / balanço / direita. Execute como pipe -nRou experimente online .

demolir

for([$a,$b,$c]=explode("\n",$argn); # import input
    $b[$i];)                        # loop through bar
    $f+=                                # add to force:
        ($i-strpos($c,"|"))             # distance (<0 if left, >0 if right of pivot)
        *8                              # *8
        *(max(1,ord($a[$i++])-31));     # *weight
echo$f<=>0;                         # print -1 if $f<0, 1 if $f>0, 0 if $f==0

1

Carvão , 31 bytes

A⁰ξFLθA⁺ξ×⁻ι⌕ζ|⁻℅§θι³¹ξI⁻›ξ⁰‹ξ⁰

Experimente online! Link é a versão detalhada do código. Saídas 0 para balanço ou -1 ou 1 para cair para a esquerda ou direita. Edit: Alterações no carvão vegetal agora significam que ≔ΣEθ×⁻κ⌕ζ|⁻℅ι³¹ξI⁻›ξ⁰‹ξ⁰funciona por 24 bytes: Experimente online! Link é a versão detalhada do código. Nota: As duas respostas requerem entrada acolchoada, mas podem ser adaptadas para aceitar entrada não acolchoada a um custo de 3 bytes: ≔⁰ξFLη≔⁺ξ×⁻ι⌕ζ|⁻℅§◨θLηι³¹ξI⁻›ξ⁰‹ξ⁰ Experimente online! ≔ΣE◨θLη×⁻κ⌕ζ|⁻℅ι³¹ξI⁻›ξ⁰‹ξ⁰ Experimente online! Os links são para a versão detalhada do código.


Você pode mencionar que isso espera que as linhas de entrada sejam preenchidas com o comprimento correto com espaços, portanto uma entrada não preenchida pode não funcionar.
FlipTack

@FlipTack Melhor ainda, criei versões que aceitam entrada não preenchida.
Neil
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.