Tambahkan bobot ke satu sisi gergaji untuk menyeimbangkannya


13

Usaha menyeimbangkan

Sebuah gergaji (yang diduga berasal dari bahasa Prancis 'ci-ça', yang berarti 'ini-itu') membentuk sepertiga dari trinitas suci peralatan bermain, bersama dengan luncuran dan ayunan yang serupa di mana-mana. Melihat-lihat adalah dalam keseimbangan sempurna jika, dan hanya jika, jumlah momen di setiap sisi adalah setara. Karenanya, gergaji dapat diseimbangkan dengan menambahkan jumlah berat tertentu ke samping dengan jumlah momen yang lebih rendah; mencapai ini adalah tujuan Anda untuk tantangan ini.

Tantangan

Tantangan Anda adalah mengambil penggambaran gergaji sebagai input dan menghasilkannya lagi, dengan bobot ditambahkan ke salah satu ujung gergaji untuk menyeimbangkannya.

Memasukkan

Program Anda harus, dalam format apa pun yang masuk akal, melihat-lihat ASCII seperti berikut ini:

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

Baris pertama berisi dua angka, masing-masing mewakili bobot pada gergaji. Persis satu bobot hadir di setiap sisi, masing-masing bekerja di ujung sisi papannya. Bobot dijamin bilangan bulat, dan selalu sejajar dengan ujung papan yang sesuai. Angka-angka ini tidak akan pernah tumpang tindih dengan titik tumpu ( ^).

Baris kedua mewakili 'papan' dari tahta. Setiap tanda hubung ( -) menunjukkan panjang yang sama dengan tanda hubung lainnya, dengan pengecualian tunggal tanda hubung langsung di atas titik tumpu ( ^), yang tidak memiliki panjang.

Baris ketiga mewakili titik tumpu dari gergaji. Titik tumpu ini ditandai oleh satu-satunya karakter yang bukan spasi pada baris ini, sirkumfleks ('^'). Titik tumpu dapat diposisikan di mana saja di sepanjang papan dalam input yang valid selama masih ada ruang yang cukup sehingga angka yang mewakili bobot tidak tumpang tindih dengan titik tumpu baik dalam input maupun output.

Input dijamin memiliki tiga baris, dan tidak memiliki ruang putih sebelum atau setelah karakter yang membentuk gergaji (kecuali, tentu saja, baris ketiga, yang memerlukannya).

Keluaran

Untuk output, penggambaran gergaji yang sama harus dicetak ke stdout, tetapi dengan satu (dan hanya satu) dari bobot diganti dengan bobot yang lebih besar, sehingga dapat menyeimbangkan gergaji. Input dijamin memungkinkan ini menggunakan integer saja. Oleh karena itu, bobot harus ditunjukkan tanpa titik desimal atau notasi serupa lainnya. Jika bahasa Anda tidak menggunakan stdout, Anda harus menggunakan konsensus komunitas / meta tentang hasil. Mengejar baris baru baik-baik saja tetapi perubahan lain pada format penggambaran mungkin tidak OK.

Contoh

Input Tes dan Output yang Sesuai

Input 1

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

Output 1

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

Input 2

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

Keluaran 2

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

Input 3

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

Keluaran 3

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

Masukan 4

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

Keluaran 4

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

Implementasi Referensi - 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",
                "-------------------",
                "    ^              "])

Aturan

  • Ini adalah , jadi kode terpendek yang menang dihitung dalam byte. Periksa meta jika menghitung byte canggung dalam bahasa Anda.

  • Aturan standar / celah berlaku.

  • Masukan harus diambil dalam format yang masuk akal. Daftar format yang sesuai tidak lengkap diberikan sebagai berikut:

    • String tunggal dengan garis yang dipisahkan oleh karakter baris baru
    • Daftar string, setiap string mewakili garis
    • Array atau Matriks karakter 2D

Tantangan Terkait



Apakah ada alasan Anda ingin output ke stdout? Kami biasanya mengizinkan fungsi untuk menghasilkan melalui nilai pengembaliannya.
corvus_192

@ corvus_192 Saya membayangkan ini sebagai tantangan jenis 'tampilan', seperti seni ASCII atau 'Gambar bendera' atau apa pun. Daftar string sebagai output tidak benar-benar 'ramah manusia' seperti itu. Jika suatu bahasa tidak memiliki dukungan stdout bawaan, bentuk keluaran lain diizinkan.
FourOhFour

Selamat datang di PPCG! Tantangan pertama yang bagus. (dan alat peraga untuk menggunakan kotak pasir di atasnya juga!)
AdmBorkBork

@TimmyD terima kasih, senang melihat bagaimana orang mengatasi masalah.
FourOhFour

Jawaban:


5

05AB1E ,60 51 50 49 47 45 byte

Disimpan 10 byte berkat Emigna dan 1 byte terima kasih kepada Adnan.

Semua jalur input harus memiliki jumlah karakter yang sama.

#õ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)

Cobalah online!

Seharusnya ada aturan praktis, seperti "jika kode 05AB1E Anda lebih panjang dari 40 byte, Anda mungkin salah melakukannya". Tampaknya begitu golf, ada ide yang menyambut!


1
Untuk memulai ¬s¤s\‚bisa õK.
Emigna

1
kD²g->(‚bisa ¡€gjika Anda menambahkan spasi yang hilang di baris bawah test case
Emigna

1
Terima kasih untuk penjelasannya. Saya melihat itu sangat mirip dengan algoritma referensi (tidak ada hal buruk) tetapi ada beberapa trik pintar di sana juga. Sesuatu tentang 05AB1E berarti mempromosikan jawaban yang lebih pintar daripada bahasa golf lainnya - ini mungkin favorit saya terutama ketika ada penjelasan yang disertakan.
FourOhFour

1
Jawaban bagus! Anda dapat mengganti 31SÍdengan 1®‚:)
Adnan

1
Bisakah Anda juga menggantinya / ïdengan ÷?
Emigna

5

JavaScript (ES6), 136

Mungkin tidak berfungsi di Chrome, karena menggunakan penugasan yang dirusak dan parameter default.

Perhatikan bahwa metode output JS standar alerttidak cocok untuk tugas tersebut, karena font proporsional yang digunakan.

(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)

Kurang golf

( 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 )

Uji

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>


Menurut kangax.github.io/compat-table/es6 , Chrome 54 sepenuhnya mendukung parameter default dan perusakan, jadi saya rasa Anda tidak perlu terlalu khawatir.
ETHproduksi

Bekerja di Chrome untuk saya.
DLosc

3

Perl, 149 + 2 = 151 karakter

Membutuhkan opsi baris perintah -p0(ini memberi saya penalti 2 byte di atas 149 byte dalam program itu sendiri).

($_,$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^"

Penjelasan:

  • The -p0beralih membaca seluruh masukan hingga byte NUL pertama atau EOF. Masalah ini tidak memungkinkan NUL, jadi kami akan mendapatkan seluruh input dalam variabel $_yang digunakan untuk regex, dll., Secara default.
  • Kita mulai dengan regex yang mem-parsing input (antara slash pertama dan kedua). Ada beberapa cara kita dapat mengurai bobot pertama (mis. .+?), Tetapi saya tidak bisa mendapatkannya di bawah 3 karakter jadi saya mungkin juga menggunakan yang sudah jelas \d+. Angka kedua adalah di akhir baris sehingga dapat diuraikan sebagai .+(2 karakter). Garis tengah digunakan untuk menentukan seberapa lebar skala; itu diuraikan sebagai -+(banyak representasi lain akan bekerja). Ruang sebelum tanda pada baris terakhir adalah +. Setelah tanda sisipan (atau memang nonspace) muncul, kita mengabaikan sisa input.
  • Perl otomatis menangkap empat kelompok regex (berat pertama, berat badan kedua, deretan tanda hubung, spasi sebelum tanda sisipan) ke $1, $2, $3, $4. Memberikan regex sebagai argumen untuk maptambahan menggunakan array dari kelompok-kelompok sebagai array untuk memetakan. Karena itu kami berusaha keras; ini adalah cara yang nyaman untuk menyimpan panjang $3dan $4tanpa harus menulis lengthdua kali. Kami juga menimpa $_dengan panjang $1; kami tidak terlalu peduli dengan nilai ini (jumlah digit pada input kiri agak tidak berguna), tetapi kenyataan bahwa itu pendek ( $_panjangnya sekarang adalah jumlah digit dalam jumlah digit pada Berat pertama, yang tentu sangat kecil dibandingkan dengan lebar timbangan).
  • Kami mengukur rasio $rdi mana skala dibagi.
  • $1*$r>$2memeriksa untuk melihat sisi mana yang lebih berat. Kami menyimpan bobot baru di $xdan $y; ini memiliki perhitungan yang sangat sederhana setelah rasio bobot diketahui.
  • Kami menggabungkan $x,, $,dan $ymenjadi $_untuk menghasilkan baris atas, kemudian terus menambahkan spasi ( $"berisi ruang tunggal secara default, dan lebih pendek dari spasi literal ' ') ke $,hingga panjangnya sama dengan baris tengah (yaitu memiliki panjang $c). (Saya memilih variabel $,karena merupakan variabel bawaan yang dapat diubah dengan aman dalam konteks ini dan mulai kosong secara default.) Saat lengthberoperasi $_secara default, kita tidak perlu memberikan argumen secara eksplisit. Saya menggunakan kondisional Yoda karena membutuhkan sintaks yang tidak terlalu membingungkan untuk menguraikan dengan benar.
  • Akhirnya, saya mendefinisikan kembali ide Perl tentang konvensi akhir garis keluaran ( $\) untuk mengandung sisa set skala (yang sama seperti pada input, jadi saya cukup menggunakan $3dan $4langsung memproduksi sebagian besar dari Perl ). Perhatikan bahwa ini berarti tidak ada spasi spasi di baris ketiga; menambahkannya akan membuat program sedikit lebih lama dan sepertinya tidak melayani tujuan apa pun, jadi saya meninggalkannya.
  • Di akhir program, -psaklar memicu lagi; kali ini, output $_diikuti oleh "baris baru" ( $\). Karena saya mendefinisikan ulang baris baru keluaran, dua cetakan tersirat ini menghasilkan set skala baru di antara mereka (meskipun sebagai efek samping, tidak ada baris baru pada output).
  • The -pberalih sekarang mencoba untuk membaca masukan lagi, tapi kita sudah menghirup seluruh file, sehingga berbunyi EOF dan berakhir program.

1

PHP, 212 209 205 byte

mungkin golf

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);

Mengambil input dari argumen baris perintah; melarikan diri dari baris baru. Jalankan dengan -r.


Mengganti dengan placeholder tidak berfungsi seperti yang diharapkan; jadi saya harus menambahkan lebih banyak parens ke regex pertama.


1

Befunge, 223 217 byte

&: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_"^",@>>

Cobalah online!


215 byte , saya pikir
Zacharý

@ Zacharý saya khawatir tidak. Setidaknya salah satu panah itu diperlukan, jika tidak maka akan gagal setiap kali torsi kiri> torsi kanan (contoh uji pertama misalnya). Yang lain >saya pikir hanya dibiarkan karena alasan estetika. Yang mengatakan, saya tampaknya memiliki solusi 215 byte dalam catatan saya, jadi mungkin saja (itu saya juga memiliki bug yang akan menjelaskan mengapa saya tidak pernah mengirimkannya - tidak punya waktu untuk mengujinya sekarang).
James Holderness

1

Python 2, 184 183 byte

Jelas golf

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+'^'

Cukup mudah. Ambil saja bobot yang disesuaikan untuk menyesuaikan kedua sisi, lihat mana yang lebih besar dari aslinya, dan ubah yang itu, dan hasilkan.

EDIT Beralih multiplikasi dan pembagian karena divisi integer adalah jahat (terima kasih kepada @JonathanAllan untuk memperhatikan ini)

EDIT -1 byte Diubah i().index('^')menjadi i().find('^')(terima kasih kepada @JonathanAllan [lagi!])


Anda harus menukar multiplikasi dan divisi karena divisi tersebut adalah divisi integer - yaitu a=[w[1]*R/I,w[0]*I/R](contoh sederhana yang tidak akan berhasil adalah a 1dan 2dengan Idan Rkeduanya 3). Saat ini 194 tidak 184 karena baris baru dihitung sebagai byte masing-masing, tetapi jdan kbiaya lebih banyak byte daripada menghemat.
Jonathan Allan

Anda dapat menggunakan I=i().find('^'), dan bentuk pendek dari __repr__, backticks untuk membuat baris terakhir print`w[0]`+' '*(W-len(`w`)+4)+`w[1]`+'\n'+'-'*W+'\n'+' '*I+'^'dan turun ke 182 - repl.it/EW8f
Jonathan Allan

0

C ++ 14, 482 byte

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;}

versi yang lebih mudah dibaca:

#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;
}

0

Python 3, 235 230 byte (referensi diperkecil)

Saya hanya meminimalkan referensi, karena saya sangat baru dalam bermain golf kode.

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))

Anda menggunakannya persis sama dengan contoh, tetapi fungsinya sbukan balance_seesaw.


Garis 5 dan 6 bisa menjadi w[o>p]=[o//k,p//t][o>p]. Juga, sebagian besar garis dapat digabungkan untuk menghilangkan ruang kosong tambahan.
James

Terima kasih, seperti yang saya katakan, saya sangat baru, jadi saya mengabaikan perbaikan yang paling sederhana.
ender_scythe

Kecuali, itu tidak berhasil, sebaliknya memberikan 0,56 bukannya 196,56.
ender_scythe
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.