Adicione peso ao lado de uma gangorra para equilibrá-lo

13

Lei de Equilíbrio

Uma gangorra (supostamente do francês 'ci-ça', que significa 'isso-aquilo') forma um terço da trindade sagrada dos equipamentos de playground, junto com o deslizamento e balanço igualmente onipresentes. Uma gangorra está em perfeito equilíbrio se, e somente se, a soma dos momentos de cada lado for equivalente. Uma gangorra pode, portanto, ser equilibrada adicionando uma quantidade específica de peso ao lado com a soma do momento mais baixo; alcançar este é o seu objetivo para este desafio.

Desafio

Seu desafio é fazer uma representação de uma gangorra como entrada e produzi-la novamente, com peso adicionado a uma extremidade da gangorra para equilibrá-la.

Entrada

Seu programa deve levar, em qualquer formato razoável, uma gangorra ASCII, como a seguinte:

100             100
-------------------
         ^         

A primeira linha contém dois números, cada um representando pesos na gangorra. Exatamente um peso está presente em cada lado, cada um atuando no final do seu lado da prancha. Os pesos são garantidos como inteiros e sempre alinhados com a extremidade correspondente da prancha. Esses números nunca se sobrepõem ao ponto de apoio ( ^).

A segunda linha representa a 'prancha' da gangorra. Cada traço ( -) representa um comprimento igual ao outro traço, com a única exceção do traço diretamente sobre o ponto de apoio ( ^), que não tem comprimento.

A terceira linha representa o ponto de apoio da gangorra. Esse ponto de apoio é marcado pelo único caractere que não é um espaço nesta linha, um circunflexo ('^'). O ponto de apoio pode ser posicionado em qualquer lugar ao longo do comprimento da prancha em uma entrada válida, desde que haja espaço suficiente para que os números que representam pesos não se sobreponham ao ponto de apoio na entrada ou na saída.

É garantido que a entrada tenha três linhas e não tenha espaço em branco antes ou depois dos caracteres que constituem a gangorra (exceto, é claro, a terceira linha, que exige isso).

Resultado

Para saída, a mesma representação da gangorra deve ser impressa em stdout, mas com um (e apenas um) dos pesos substituídos por um peso maior, para equilibrar a gangorra. As entradas são garantidas para tornar isso possível usando apenas números inteiros. Portanto, os pesos devem ser mostrados sem pontos decimais ou outras notações semelhantes. Se o seu idioma não usa stdout, você deve concordar com a comunidade / meta meta na saída. As novas linhas à direita são boas, mas qualquer outra alteração no formato da representação provavelmente não está correta.

Exemplificação

Entradas de teste e saídas correspondentes

Entrada 1

12                22
--------------------
             ^      

Saída 1

12                26
--------------------
             ^      

Entrada 2

42       42
-----------
     ^     

Saída 2

42       42
-----------
     ^     

Entrada 3

3             16
----------------
        ^      

Saída 3

14            16
----------------
        ^      

Entrada 4

1                56
-------------------
    ^              

Saída 4

196              56
-------------------
    ^              

Implementação de referência - Python 3

# Takes a list of strings as input
def balance_seesaw(lines):
    weights = [int(w.strip()) for w in lines[0].split()]

    length  = len(lines[1])
    pivot   = lines[2].find("^")
    left_length    = pivot
    right_length   = length - 1 - pivot

    left_torque  = weights[0] * left_length
    right_torque = weights[1] * right_length

    if left_torque > right_torque:
        weights[1] = left_torque // right_length
    elif right_torque > left_torque:
        weights[0] = right_torque // left_length

    weights = [str(w) for w in weights]

    string_gap = " " * (length - sum(len(w) for w in weights))
    lines[0] = weights[0] + string_gap + weights[1]

    print("\n".join(lines))

balance_seesaw(["1                56",
                "-------------------",
                "    ^              "])

Regras

  • Isso é , então o código mais curto vence contado em bytes. Verifique a meta se a contagem de bytes é estranha no seu idioma.

  • Regras / lacunas padrão se aplicam.

  • A entrada deve ser obtida em um formato razoável. Uma lista não exaustiva dos formatos apropriados é fornecida da seguinte maneira:

    • Uma única sequência com linhas separadas por caracteres de nova linha
    • Uma lista de cadeias, cada cadeia representava uma linha
    • Uma matriz 2D ou matriz de caracteres

Desafios relacionados


FourOhFour
fonte
Existe algum motivo para você desejar que o stdout de saída? Geralmente, permitimos que as funções produzam através de seu valor de retorno.
corvus_192
@ corvus_192 Eu imaginei isso como um desafio do tipo 'exibição', como uma arte ASCII ou 'Desenhar uma bandeira' ou qualquer outra coisa. Uma lista de seqüências de caracteres como saída não é realmente 'amigável ao ser humano', como tal. Se um idioma não possui suporte stdout embutido, outros formulários de saída são permitidos.
FourOhFour
Bem-vindo ao PPCG! Bom primeiro desafio. (e adereços para usar a caixa de areia sobre ele, também!)
AdmBorkBork
@ TimmyD obrigado, foi muito divertido ver como as pessoas lidam com o problema.
FourOhFour

Respostas:

5

05AB1E ,60 51 50. 49. 47 45 bytes

Economizou 10 bytes graças a Emigna e 1 byte graças a Adnan.

Todas as linhas de entrada devem ter a mesma quantidade de caracteres.

#õKD³'^¡€gDŠ*¬-Os÷1®‚*D0›*+¬?DJg²gs-ð×?¤,²,³,

#                                             Split the first input line on spaces
 õKD                                          Push [first weight, second weight] twice
    ³'^¡€gD                                   Push both lengths from either side of the pivot '^' as an array [left, right] twice
           Š*                                 Multiply by weights to get torque
             ¬-O                              Evaluate rightTorque-leftTorque
                s÷                            Divide by each side's length to get the weights to add: [deltaLeft, deltaRight], keep integer values
                  1®‚                         Push [1,-1]
                     *D                       Yield [deltaLeft, -deltaRight]
                       0›*                    Replace the negative value by 0
                          +                   Add weights: old + deltaWeight
                           ¬?                 Print left weight
                             DJg              Take the size of total decimal representation
                                ²gs-ð×?       Print a string composed of filler spaces between both new weights
                                       ¤,     Print right weight and newline
                                         ²,³, Print the last two lines from input (unchanged)

Experimente online!

Deve haver uma regra geral, como "se o seu código 05AB1E tiver mais de 40 bytes, você provavelmente está fazendo errado". Parece tão fácil de jogar, qualquer idéia é bem-vinda!

Osable
fonte
1
Para um começo ¬s¤s\‚pode ser õK.
Emigna
1
kD²g->(‚pode ser ¡€gse você adicionar os espaços ausentes na linha inferior do caso de teste
Emigna
1
Obrigada pelo esclarecimento. Vejo que é bastante semelhante ao algoritmo de referência (nada ruim), mas há alguns truques inteligentes também. Algo no 05AB1E significa que parece promover respostas mais inteligentes do que algumas outras línguas do golfe - talvez seja a minha favorita, especialmente quando há uma explicação incluída.
FourOhFour
1
Boa resposta! Você pode substituir 31SÍcom 1®‚:)
Adnan
1
Você também pode substituir / ïpor ÷.?
Emigna
5

JavaScript (ES6), 136

Provavelmente não está funcionando no Chrome, pois usa atribuição desestruturada e parâmetros padrão.

Observe que o método de saída JS padrão alerté particularmente inadequado para a tarefa, devido à fonte proporcional usada.

(m,n,o,[p,q]=m.split(/ +/),l=n.length,h=o.indexOf`^`,g=l-h-1,c=p*h<q*g?q*g:p*h)=>alert((c/h+o).slice(0,h)+(o+c/g).slice(h-l)+`
${n}
`+o)

Menos golfe

( m,n,o, // input parameters, 3 strings
  // default parameters used as local variables
  [p,q] = m.split(/ +/), // left and right weight
  l = n.length, // bar length
  h = o.indexOf`^`, // left length
  g = l-h-1, // right length
  // p*h left torque
  // q*g right torque
  c = p*h<q*g ? q*g : p*h // max torque
) => alert( (c/h+o).slice(0,h)+(o+c/g).slice(h-l) // o has enough spaces to pad left and right
     +`\n${n}\n`+o )

Teste

F=
(m,n,o,[p,q]=m.split(/ +/),l=n.length,h=o.indexOf`^`,g=l-h-1,c=p*h<q*g?q*g:p*h)=>alert((c/h+o).slice(0,h)+(o+c/g).slice(h-l)+`
${n}
`+o)

function go()
{
  var [a,b,c]=I.value.split('\n')
  if(a.length!=b.length || a.length < c.length)
    alert('The strings are not of the same length')
  else 
  {  
    if (a.length > c.length)
      c = c+' '.repeat(a.length-c-length)
    F(a,b,c)
  }  
}
<textarea id=I>3             16
----------------
        ^      </textarea>
<button onclick='go()'>go</button>

edc65
fonte
De acordo com kangax.github.io/compat-table/es6 , o Chrome 54 suporta totalmente os parâmetros padrão e a desestruturação, portanto, acho que você não precisa se preocupar muito.
ETHproductions
Funciona no Chrome para mim.
DLosc
3

Perl, 149 + 2 = 151 caracteres

Requer opções de linha de comando -p0(isso me dá uma penalidade de 2 bytes sobre os 149 bytes no próprio programa).

($_,$b,$c,$d)=map length,/(\d+) +(.+)
(-+)
( +)/;$r=$d/($c-$d-1);($x,$y)=$1*$r>$2?($1,$1*$r):($2/$r,$2);$_="$x$,$y",$,.=$"while$c>length;$\="
$3
$4^"

Explicação:

  • O -p0switch lê toda a entrada até o primeiro byte NUL ou EOF. Como esse problema não permite NULs, obteremos toda a entrada na variável $_usada para expressões regulares etc., por padrão.
  • Começamos com uma regex que analisa a entrada (entre a primeira e a segunda barra). Existem várias maneiras pelas quais podemos analisar o primeiro peso (por exemplo .+?), mas não posso obtê-lo abaixo de três caracteres, para que eu possa usar o óbvio \d+. O segundo número está no final da linha para que possa ser analisado como .+(2 caracteres). A linha central é usada para determinar a largura das escalas; é analisado como -+(muitas outras representações funcionariam). Os espaços antes do cursor na última linha são +. Depois que o sinal de intercalação (ou mesmo qualquer não-espaço) aparece, ignoramos o restante da entrada.
  • Perl captura automaticamente os quatro grupos do regex (primeiro peso, segundo peso, Fila de hífens, espaços antes o acento circunflexo) em $1, $2, $3, $4. Fornecer uma regex como argumento para mapusar adicionalmente uma matriz desses grupos como a matriz a ser mapeada. Nós, portanto, nos esforçamos; Essa é uma maneira conveniente de armazenar os comprimentos $3e $4sem precisar escrever lengthduas vezes. Também substituímos $_o comprimento de $1; nós realmente não nos importamos com o valor disso (o número de dígitos na entrada esquerda é meio inútil), mas o fato de ser curto ( $_o comprimento agora é o número de dígitos no número de dígitos na primeiro peso, que é necessariamente muito pequeno comparado à largura das balanças).
  • Medimos a proporção $rna qual as escalas são divididas.
  • $1*$r>$2verifica para ver qual lado é mais pesado. Armazenamos os novos pesos em $xe $y; estes têm cálculos muito simples quando a relação de pesos é conhecida.
  • Concatenamos $x, $,e $yinto $_para produzir a linha superior, e continuamos adicionando espaços ( $"contém um único espaço por padrão e é mais curto do que um espaço literal ' 'seria) $,até que ele tenha o mesmo comprimento que a linha do meio (ou seja, tenha comprimento $c). (Escolhi a variável $,por ser uma variável interna que pode ser alterada com segurança nesse contexto e começa vazia por padrão.) Como lengthopera $_por padrão, não precisamos fornecer um argumento explicitamente. Eu usei um condicional Yoda porque ele precisa de uma sintaxe consideravelmente menos desambiguação para analisar corretamente.
  • Por fim, redefino a ideia de Perl da convenção de término da linha de saída ( $\) para conter o restante do conjunto de escalas (que é o mesmo da entrada, para que eu possa simplesmente usar $3e $4diretamente para produzir a maior parte dela). Observe que isso significa que não há espaço em branco à direita na terceira linha; adicioná-lo tornaria o programa um pouco mais longo e não parece servir a nenhum propósito, então deixei de fora.
  • No final do programa, o -pswitch é acionado novamente; desta vez, ele sai $_seguido por uma "nova linha" ( $\). Como redefini a nova linha de saída, essas duas impressões implícitas geram o novo conjunto de escalas entre elas (embora, como efeito colateral, não haja nova linha na saída).
  • O -pswitch agora tenta ler a entrada novamente, mas já descartamos o arquivo inteiro, então ele lê EOF e finaliza o programa.

fonte
1

PHP, 212 209 205 bytes

provavelmente jogável

preg_match("#(\d+)( +)(\d+)\s*(-+)[\r\n]+( +)\^#",$s=$argv[1],$m);echo preg_replace("#\d+( +)\d+#",(($r=$m[3])>($q=$m[1]*($p=strlen($m[5]))/(-$p-1+$e=strlen($m[4])))?$r*$e/($p+1)-$q=$r:$m[1]).$m[2].$q,$s);

Recebe entrada do argumento da linha de comando; escapar de novas linhas. Corra com -r.


A substituição por um espaço reservado não funcionou conforme o esperado; então eu tive que adicionar mais parênteses ao primeiro regex.

Titus
fonte
1

Befunge, 223 217 bytes

&:00p&10p~$0>~#<2#+%#1_:20p0~>8#~%#+!#1_:3v
v\g01/g03*g01_v#!\g04`*g01g04:*g03p04-1-p0<
>#g>#0>#0>#/>#<:.2\5>5>#\+/#1:#\_$50p:50g\5>5>#\+/#1:#\_$20g\-v>
1#,>#*-#4:#8_$.55+,20g>:#,1#*-#9\#5_55+,30g>:#,1#*-#8\#4_"^",@>>

Experimente online!

James Holderness
fonte
215 bytes , eu acho
Zachary
@ Zacharý, receio que não. Pelo menos uma dessas setas é necessária; caso contrário, ela falhará sempre que o torque esquerdo> torque direito (o primeiro caso de teste, por exemplo). >Acho que o outro foi deixado por razões estéticas. Dito isso, parece que tenho uma solução de 215 bytes em minhas anotações, por isso é possível (também tenho bugs que explicariam por que nunca a enviei - não tenho tempo para testá-la agora).
James Holderness
1

Python 2, 184 183 bytes

Definitivamente jogável

i=raw_input
j=int
w=map(j,i().split())
W=len(i())
I=i().find('^')
R=W-I-1
a=[w[1]*R/I,w[0]*I/R]
h=a[1]>w[1]
w[h]=j(a[h])
k='\n'
print(' '*(W-len(str(w))+4)).join(map(str,w))+k+'-'*W+k+' '*I+'^'

Bem direto. Pegue os pesos ajustados para ajustar os dois lados, veja qual é maior que o original e troque-o e a saída.

EDIT Multiplicação e divisão comutada porque a divisão inteira é ruim (obrigado a @ Jonathanon Allan por perceber isso)

EDIT -1 byte Alterado i().index('^')para i().find('^')(graças a @JonathanAllan [novamente!])

HyperNeutrino
fonte
Você deve trocar a multiplicação e a divisão, pois a divisão é uma divisão inteira - ou seja, a=[w[1]*R/I,w[0]*I/R](um exemplo simples que não funcionaria seria a 1e 2with Ie Rboth 3). Atualmente 194 não 184 pelo caminho desde as novas linhas contam como um byte de cada um, mas je kestão custando mais bytes do que salvar.
Jonathan Allan
Você pode usar I=i().find('^'), e a forma abreviada __repr__, backticks para fazer a última linha print`w[0]`+' '*(W-len(`w`)+4)+`w[1]`+'\n'+'-'*W+'\n'+' '*I+'^'e descer para 182 - repl.it/EW8f
Jonathan Allan
0

C ++ 14, 482 bytes

include<iostream>#include<string>#include<math.h>usingnamespacestd;intmain(){stringa,b,c,d;intj=0;inte[2];getline(cin,a);getline(cin,b);getline(cin,c);for(inti=0;i<a.size();i){if(isdigit(a.at(i))){while(i<a.size()&&isdigit(a.at(i))){d=a.at(i);i;}e[j]=stoi(d);d="";}}strings(b.size()-(int)log10(e[0])-(int)log10(e[1])-2,'');intl1=(c.size()-1);intl2=(b.size()-c.size());intl=e[0]*l1;intr=e[1]*l2;if(l>r)e[1]=l/l2;elsee[0]=r/l1;cout<<e[0]<<s<<e[1]<<endl;cout<<b<<endl;cout<<c;return0;}

versão mais legível:

#include <iostream>
#include <string>
#include <math.h>
using namespace std;
int main() {
    string a,b,c,d;
    int j=0;
    int e[2];
    // input
    getline(cin,a);// 1st line
    getline(cin,b);// 2nd line
    getline(cin,c);// 3rd line
    for (int i=0;i<a.size();i++) {
        if(isdigit(a.at(i))){
            while(i<a.size() && isdigit(a.at(i))){
                d+=a.at(i);
                i++;
            }
            e[j++]=stoi(d);
            d="";
        }
    }
    // amount of white space in between 2 numbers
    string s(b.size()-(int)log10(e[0])-(int)log10(e[1])-2,' ');
    int l1 = (c.size()-1);
    int l2 = (b.size()-c.size());
    int l = e[0]*l1;
    int r = e[1]*l2;
    // change the side with smaller torque
    if (l>r)
        e[1]=l/l2;
    else
        e[0]=r/l1;
    // output
    cout<<e[0]<<s<<e[1]<<endl;// 1st line
    cout<<b<<endl;// 2nd line
    cout<<c;// 3rd line
    return 0;
}
Bobas_Pett
fonte
0

Python 3, 235 230 bytes (referência minimizada)

Acabei de minimizar a referência, já que sou muito novo no código de golfe.

def s(l):
 w,i,t=[int(z.strip())for z in l[0].split()],len(l[1]),l[2].find("^");k,o=i-1-t,w[0]*t;p=w[1]*k
 if o>p:w[1]=o//k
 else:w[0]=p//t
 w=[str(z)for z in w];s=" "*(i-sum(len(z)for z in w));l[0]=w[0]+s+w[1];print("\n".join(l))

Você o usa exatamente da mesma forma que no exemplo, mas a função é em svez de balance_seesaw.

ender_scythe
fonte
As linhas 5 e 6 podem se tornar w[o>p]=[o//k,p//t][o>p]. Além disso, a maioria das linhas pode ser unida para se livrar de algum espaço em branco extra.
James
Obrigado, como eu disse, sou muito novo, então negligencio até as correções mais simples.
Ender_scythe #
Exceto, ele não funciona, fornecendo 0,56 em vez de 196,56.
Ender_scythe #