Врівноважте набір ваг на пилянці


32

Закон про балансування

Огляд

За умови введення 3 одноцифрових натуральних чисел, що представляють собою набір ваг, виведіть ASCII подання пила з розміщеними на ньому вагами, щоб воно було в рівновазі навколо центрального стрижня, враховуючи ефекти важеля.

Кожне число має вагу, рівну його вартості. Крутний момент кожного числа - це вага, помножена на відстань від центру в символах. Щоб пило врівноважилось, сума крутного моменту ваг зліва від пилки повинна дорівнювати тій, що знаходиться праворуч, як це .

Вхідні дані

3 цілих числа в діапазоні 1-9. Ви можете вводити цілі числа, однак це зручно, наприклад, кортеж, 3 значення, розділені комами і т. Д. Однак ваша програма повинна вміти обробляти введення чисел у будь-якому порядку (тобто не передбачаючи сортування значень). Можуть бути введені повторювані номери (наприклад, 2,3,2).

Входи завжди математично дозволять отримати дійсний вихід, інакше введення недійсне.

Вихід

На виході має бути дворядне ASCII представлення пилки з розміщеними на ньому вагами. На першому рядку розміщені цифри, розташовані на відстані, щоб збалансувати їх на пилу.

Числа не можуть бути розміщені в самому центрі шкали, де відстань і, отже, крутний момент буде нульовим. Дійсні відстані від центрального діапазону від 1-10 символів включно ліворуч або праворуч від стрижня.

У місцях, не зайнятих цифрами, є 18 символів підкреслення (центр підкреслення і 10 з кожного боку, мінус 3 позиції, зайняті цифрами). На останньому рядку - один символ каретки, вирівняний із центром шкали, що представляє стрижень.

Приклади

Вхід:

4,7,2

Вихід:

________7___42_______
          ^

7 * 2 = 4 * 2 + 2 * 3

Числа можна виводити з будь-якої сторони, наприклад, це також було б дійсним:

_______24___7________
          ^

2 * 3 + 4 * 2 = 7 * 2

Числа можна розміщувати в будь-якому місці шкали, якщо вони балансують, наприклад:

Вхід:

3,1,5

Вихід:

_____5________1__3___
          ^

5 * 5 = 1 * 4 + 3 * 7

або

____5________1_____3_
          ^

5 * 6 = 1 * 3 + 3 * 9

або

____5___________1_3__
          ^

5 * 6 = 1 * 6 + 3 * 8

тощо

Ваша програма повинна вивести лише один з дійсних результатів. Він не повинен виводити помилку, якщо введення недійсне.

Примітки

  • Це тому виграє найкоротша програма в байтах
  • Програма може бути окремою або функцією, яка приймає числа як вхідні та повертає рядок.
  • Обмежування нового рядка та пробілів на останньому рядку необов’язкове
  • Якщо ви не знаєте, що таке пиляння , він також відомий як тітер або тітер.

Ось паста, де відображаються дійсні дані та рішення (з деяким дублюванням)
samgak

11
Чудовий перший виклик! Цікава проблема та ретельна специфікація.
xnor

2
Алгоритмічно, враховуючи цілочислений вектор, це вимагає від вас знайти цілочислений ортогональний вектор з усіма різними записами.
гордий haskeller

Відповіді:


13

CJam, 40 39 38 байт

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

Спробуйте в Інтернеті.

Як це працює

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.

5

CJam, 46 44 байти

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

Тестуйте це тут.

Пояснення

По-перше, спостереження: нам ніколи не потрібно ставити дві цифри на кінцях пилки. Щоразу, коли це правильне рішення, є щонайменше ще одне дійсне рішення (згідно пастебіну в коментарі до виклику).

'_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.

5

Java, 519 414 321 байт

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

Моя перша спроба гольфу.

Ви можете зателефонувати за допомогою f(a,b,c). Спробуйте тут

EDIT: Використовується метод перевірки izlin(a*i+b*j+c*k)==0

EDIT: Спасибі, Дж. Аткін за пропозиції щодо гольфу.


1
Ви можете заощадити кілька байт, змінивши підпис pдо Object aі використовувати його замість інших 2 System.out.print(ln)с.
J Atkin

1
А оскільки aвикористовується лише один раз, ви можете вкласти її.
Дж. Аткін

5

Pyth, 67 58 53 49 байт

Це відчуває трохи з величезного боку для Pyth, але я майже не знайомий з мовою, щоб можна було отримати це набагато менше. Sub 50 байт, я нарешті задоволений цим!

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

Наприклад, введення очікується як масив цілих чисел [1,2,3]. Спробуйте тут.

Пояснення:

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

І, нарешті, кілька прикладів входів та виходів:

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

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

[9,8,5] ->
5____8______________9
          ^

4

С - 237 228 байт

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

Ви можете зателефонувати за допомогою f(a,b,c).

Спробуйте тут .

Приклади виходів:

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

f(3,1,5)
3____1___________5___
          ^       

3

Python 2.7 235 226 219 байт

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

Тестування його за допомогою деяких основних прикладів - дає (1,1,1),(1,2,1),(3,1,5),(4,7,2)результати:

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

Вихідні дані для всіх можливих вкладених тут входів


"".join(l) -> 'l'[2::5]є на один байт коротшим (замініть лапки на задній план).
Каде

Крім того, якщо ви готові змінити свій підхід з функції на програму, ви можете переграти цю програму до 222 байт.
Каде

@samgak на жаль. Моє погано, думав, що правильно прочитав питання. Ще 2 байти :(
Камехамега

@ Віоз - дивовижна порада. Не знав про repr. :)
Камехамега

3

PHP, 278 байт

Рішення з грубою силою, яке використовує купу вкладених циклів і пару тестів.

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

Як завжди, помістіть його у файл (назвемо його seesaw.php), з'єднайте рядки (розділіть тут для читабельності), поставте маркер PHP (<?php ) на початок файлу (технічно це не є частиною програми) і ви ' З тобою добре піти.

Приклад виконання:

$ 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_
          ^

Він генерує та відображає всі рішення (без роздумів), але не знімає дублікатів (коли вхідні значення містять дублікати).


3

Джулія, 154 байти

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*"^"))

Недоліковані + пояснення:

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

2

C, 252 (214) байт

Виклик за допомогою a, b, c як аргументів у командному рядку.

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

Якщо основне можна опустити, кількість байтів падає до функції 214.

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

Обидва використовують одну і ту ж стратегію розміщення першого ваги зліва, потім сканування вздовж можливих других вагових позицій і обчислення третьої ваги. Це дозволяє зняти внутрішню петлю.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.