Падіння кульок ASCII


16

Вхідні дані

Вам дається двовимірна карта з кулями і землею в ній. Це виглядає приблизно так:

  1         5          2
                 3
     4


__________________________

Кожне число - це кулька, а _рівень землі. Символ підкреслення _не дозволений в жодному іншому рядку, крім лінії рівня землі. Є лише пробіли, нові рядки та цифри, 0-9дозволені над рівнем землі. Ви не можете припустити, що останній рядок є рівнем землі - пусті рядки нижче рівня землі дозволені. Ви також можете додавати пробіли для заповнення порожніх рядків, якщо це допоможе вам.

Кульки можуть мати числа від 0до 9, можуть бути розміщені один над одним, але не під землею. Номери кулі будуть унікальними.

Припустимо, що кожен символ - один метр .

Отримайте карту з пастебіну!
Тестовий випадок 1 - повинен вивести щось подібне до цього
Тестовий випадок 2 - повинен дати ті ж результати, що і перша карта

Виклик

Ваше завдання полягає в тому, щоб прочитати таку карту з файлу чи з stdin- вам дозволяється використовувати cat balls.txt | ./yourexecutable- та вивести швидкість кожного кулі, коли він потрапляє на землю.

Ось формула швидкості:

enter image description here

Припустимо, що hце різниця чисел у рядку між номером лінії землі та номером лінії кулі, що gдорівнює 10m/s^2.

Вихідні дані

Ви повинні виводити число та швидкість кожного кулі m/sна рівні землі. Наприклад N - Vm/s, де Nчисло кулі і Vяка його швидкість. Ви також можете вивести масив, якщо хочете.

Щасливого кодування! :)


Тестові приклади без очікуваного результату не є тестовими кейсами
edc65

@ edc65 До питання я додав очікувані результати
Jacajack,

Чи добре, якщо я беру каталог як вхід від користувача як частину програми?
Даніель

@Dopapp Що саме ти маєш на увазі?
Jacajack

Дивіться мою відповідь .
Даніель

Відповіді:


8

MATL , 31 30 27 25 байт

95\16\5B#fG&X>1)b- 20*X^h

Вхід - це двовимірний масив символів з ;роздільником рядків:

['  1         5          2  ';'                 3        ';'     4                    ';'                          ';'                          ';'__________________________']

Спробуйте в Інтернеті! Або включіть tв код початковий, щоб відобразити карту для більшої чіткості.

Ось інші тестові випадки: перший , другий .

Пояснення

95\      % Take input implicitly. Modulo 95: convert to numbers and map '_' into 0
16\      % Modulo 16: map space into 0 and digit chars into corresponding numbers
5B#f     % Find row indices and values of nonzero entries
G        % Push input again
&X>      % Index of maximum of each column. This finds character '_'
1)       % Get first value (they are all equal)
b        % Bubble row indices of numbers up in the stack
-        % Subtract to get distance from each number to the ground
20*X^    % Multiply by 20, take sqrt. This gives the velocity values
h        % Horizontally concat numbers and velocities. Display implicitly

7

C, 125 122 121 байт

b[99]={};main(l,c){for(;(c=getchar())<95u;)b[c]=(l+=c==10);for(c=47;++c<58;)b[c]&&printf("%c,%f\n",c,sqrt((l-b[c])*20));}

Скомпілювати та запустити gcc -w golf.c -lm && cat balls.txt | ./a.out.


Це справді чудово, сер! Я не говорив про це в своєму запитанні, але хотів би, щоб ви знали, що ваш приклад нічого не виводить, коли 0 ... 9в текстовому файлі немає іншого символу, ніж зустрічається. У всякому разі, +1, бо я не
вказую на

@Jacajack Ні, будь-який символ є прекрасним, якщо він не містить символу з кодом ASCII більше, ніж _. Однак це може бути виправлено одним додатковим байтом ( !=замість <).
orlp

Ну, я використовував 'x' для тестування. Не зважай. Ваш код чудовий :)
Jacajack

@Jacajack У новій версії це вже не один виправлення символів, але я врятував ще 3 байти :)
orlp

Приємно! :) Я погляну, що я можу зробити зі своїм кодом, коли повернусь додому. Я знаю, що його можна значно скоротити, але я не хочу, щоб він був вашою копією: p
Jacajack,

6

С - 194 (-5) 150 137 байт

Трохи більше часу та роздумів я зіграв на 44 байти
завдяки Орлпу за допомогу мені зберегти 13 байт

Почну з мого коду С:

b[256]={},n,i=47;main(l,c){for(;~(c=getchar());n=c==95?l:n)b[c]=(l+=c==10);for(;++i<58;)b[i]&&printf("%d %f\n",i-48,sqrt((n-b[i])*20));}

І читана людиною версія:

//Throws many warnings, but lack of libraries is tolerated

/*
    c - current character
    l - line number (starts at 1)
    n - ground level
    i - iterator
    b - balls array
*/

b[256] = {}, n, i = 47; //That actually works, as long as you are using ASCII

main( l, c )
{
    for ( ;~( c = getchar( ) ); n = c == 95 ? l : n ) //Read stdin and search for ground
        b[c] = ( l += c == 10 ); //Increment lines counter on newlines, and save line numbers

    for ( ; ++i < 58; ) //Iterate through balls
        b[i] && printf( "%d %f\n", i - 48, sqrt( ( n - b[i] ) * 20 ) ); //Print out data    
}

Складіть і запускайте так: gcc -o balls ballsgolf.c -lm && cat 1.txt | ./balls

Вихідні дані

1 10.000000
2 10.000000
3 8.944272
4 7.745967
5 10.000000

Збережіть 4 байти: ~(c=getchar())замість (c=getchar())!=EOF.
marinus

@marinus Це я мав.
orlp

1
if (x != -1)те саме, що if (~x)(на двох машинах, що доповнюють), оскільки ~-1є (однозначно) 0. У C гольф ніколи не користуються while(cond), так як for(;cond;)це так само довго і надає більше можливостей для гри в гольф. У вашому прикладі це може стати for(;~(c=getchar());n=c==95?l:n)b[c]=(l+=c==10);.
orlp

@orlp Я розумію, дякую за пораду :)
Jacajack

1
l=1можна обійти, зробивши lперший аргумент для main, оскільки час виконання C передає кількість аргументів main як його перший аргумент ( argc), а коли ви викликаєте програму без будь-яких аргументів командного рядка ( ./a.out), то argc = l = 1. n=0;не є зайвим, оскільки глобальні цілі числа автоматично ініціалізуються на 0. Тож просто n;вистачить.
orlp

4

Pyth, 27 26 25 24 байт

smf-hT "_". e, b @ * 20-xd \ _k2dC 
smf @ hT`M; .e, b @ * 20-xd \ _k2dC 
smf @ T`M; .e, b @ * 20-xd \ _k2dC
sm @ # `M; .e, b @ * 20-xd \ _k2dC

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



@orlp О, я думав, що рівень землі може бути лише в останньому рядку.
Лина монашка



1
@orlp У правилах "Ви можете додати пробіли, щоб заповнити порожні рядки, якщо це допоможе вам".
Лина монашка

3

Матлаб, 100 96 89 90 байт

s=input('');X=find(s==95);for i=0:9
[x y]=find(s==48+i);if(x)[i sqrt(20*(X(1)-x))]
end
end

Багато байтів збереглися завдяки Луїсу Мендо

Формат введення:

['  1         9          2  ';'                 3        ';'     4                    ';'                          ';'                          ';'__________________________']

Пояснення:

X=find(s==95)         -- finds '_', we'll need X(1) to determine max height
for i=0:9             -- loops through balls' numbers
[x y]=find(s==48+i)   -- finds the ball
if(x)                 -- if it is present
[i sqrt(20*(X(1)-x))] -- output its number and velocity

3

Пітон 3, 84 байти

Версія 6, 84 байти: (Дякую монахині!)

lambda a:[(c,(~-(len(a)-i)*20)**.5)for i,s in enumerate(a)for c in s if c.isdigit()]

Версія 5, 91 байт:

lambda a:[c+":"+str((~-(len(a)-i)*20)**.5)for i,s in enumerate(a)for c in s if c.isdigit()]

Версія 4, 92 байти:

lambda i:[c+":"+str((~-(len(i)-n)*20)**.5)for n in range(len(i))for c in i[n]if c.isdigit()]

Версія 3, 99 байт:

def r(i):x=len(i);print([c+":"+str((~-(x-n)*20)**.5)for n in range(x)for c in i[n] if c.isdigit()])

Версія 2, 102 байти:

def r(i):
 n=len(i)
 for l in i:
  for c in l:
   if c.isdigit():print(c+":"+str((~-n*20)**.5))
  n-=1

Вищеописані версії беруть масив рядків як вхідний.

Версія 1, 140 байт:

with open(input(),"r")as i:
 n=sum(1for l in i);i.seek(0)
 for l in i:
  for c in l:
   if c.isdigit():print(c+":"+str((~-n*20)**.5))
  n-=1

Це сприймає каталог файлу як вхід від користувача.


1 for l in i->1for l in i
Лина монашка

@LeakyNun, чи працює ця хитрість із усіма ключовими словами та цифрами?
Даніель

1
Я так думаю. Також, (n-1)*20->~-n*20
Leaky Nun

1
Зачекай. Чи не потрібен Python3 дужки з printвикликом?
Yytsi

1
@LeakyNun Ні, це не працює для всіх ключових слів і чисел у Python 2. Це спеціально не працює для ключових слів, починаючи з e , тому що тоді токенізатор Python спробує розібрати його як наукове позначення з плаваючою комою (наприклад 1e5). Приклад , який зазнає поразки: f = lambda n:-1if n<0else 1. Приклад, який не вдається в обох версіях Python 0or 1, тому що токенізатор думає, що 0oпочинає восьмеричне число.
orlp

2

Пітон 3, 84 байти

lambda x:[[i,(20*x[x.find(i):x.find('_')].count('\n'))**.5]for i in x if i.isdigit()]

Анонімна функція, яка приймає введення за аргументом як багаторядковий рядок із усіма порожніми рядками, заповненими пробілами, і повертає масив, де кожен елемент має форму [номер кулі, швидкість].

Як це працює

lambda x                      Function with input x
...for i in x if i.isdigit()  Loop through all characters i in x for which i is a digit,
                              and hence one of the balls
x[x.find(i):x.find('_')]      Slice x to give the substring between the ball and the ground
....count('\n')               Count the number of newlines in the substring to give the
                              height of the ball
(20*...)**.5                  Calculate the speed of the ball as it hits the ground
[i,...]                       Package the ball number and speed into a list
:[...]                        Return all ball-speed pairs as a list with elements [ball
                              number, speed]

Спробуйте це на Ideone


У цьому випадку, я думаю, це фрагмент коду, а не повний автономний скрипт Python, чи не так?
Jacajack

@Jacajack Це насправді функція, а не фрагмент, який дозволений за замовчуванням . У Python лямбда-функції - це функції без імені, які можна призначити змінній і потім викликати, коли потрібно; Ви можете написати f = MyAnswer, а потім зателефонувати за допомогою f(x). Існує консенсус, що не потрібно називати лямбда . Приємний виклик, до речі!
TheBikingViking

Звичайно, я просто думав, що тут лямбди вважаються фрагментами коду ( meta.codegolf.stackexchange.com/a/1146/55729 ). Я гадаю, тоді все добре. Дякую за вашу думку :)
Jacajack

2

JavaScript (ES6) 93

Редагуйте 2 байти, збережені thx @Jacajack

Функція з багаторядковим рядком як вхідний параметр. Вихідні дані не сортуються (оскільки це не запитується)

a=>[...a].reverse().map(c=>c>'Z'?b=i:c<' '?++i:c>' '&&console.log(c,Math.sqrt((i-b)*20)),i=0)

Тест

F=
a=>[...a].reverse().map(c=>c>'Z'?b=i:c<' '?++i:c>' '&&console.log(c,Math.sqrt((i-b)*20)),i=0)

function test()
{
  F(I.value);
}

test()
#I { height: 12em; width: 30em}
<textarea id=I>
    
 
  1         5          2
                 3
     4


__________________________




</textarea>
<button onclick="test()"></button>


Не sqrt(x)буде коротше pow(x,.5)?
Jacajack

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