Намалюйте дугу кулі


35

Намалюйте параболічну траєкторію закинутої кулі.

Вхід - початкова швидкість вгору кулі, додатне ціле число v. Кожну секунду м'яч рухає 1простір праворуч і vпростір вертикально, а потім vзменшується на 1за рахунок сили тяжіння. Таким чином, швидкість вгору в кінцевому підсумку кроків вниз від vдо 0і вниз -v, в кінці кінців падає назад вниз до його первісної висоті.

Положення м'яча простежують параболу. У горизонтальному положенні x, його висота y=x*(2*v+1-x)/2, з (0,0)початковим положенням кулі в нижньому лівому кутку .

Вивести ASCII мистецтво траєкторії кулі з O's на координатах, які він колись займає. Вихід повинен бути одним багаторядковим фрагментом тексту, а не анімацією шляху в часі.

У висновку не повинно бути провідних нових рядків і максимум один кінцевий новий рядок. Нижній рядок повинен бути врівень з лівим краєм екрана, тобто не мати зайвих провідних пробілів. Пробіли в порядку. Ви можете припустити, що ширина вихідного рядка вписується у вихідний термінал.

v = 1

 OO 
O  O

v = 2

  OO  
 O  O 

O    O

v = 3

   OO   
  O  O  

 O    O 


O      O

v = 4

    OO    
   O  O   

  O    O  


 O      O 



O        O

v = 10

          OO          
         O  O         

        O    O        


       O      O       



      O        O      




     O          O     





    O            O    






   O              O   







  O                O  








 O                  O 









O                    O

Супутнє: Моделювання м'яча підстрибуючим


Табло:


Чи можемо ми випустити список рядків?
Rɪᴋᴇʀ

@Riker Nope, рядок з новими рядками.
xnor

слабко пов’язаний: codegolf.stackexchange.com/q/110410
Тит

Чи потрібно мені рахувати лише V> 0?
nmjcman101

Так, v буде позитивним.
xnor

Відповіді:


17

Вугілля , 18 16 13 байт

-3 байти завдяки @Neil !

F⊕N«←OM⊕ι↓»‖C

Пояснення

F⊕N«        »    For ι (implicitly from 0) to (1 + input as number)
       ←O          Print O, with print direction rotated 180 degrees
         M⊕ι↓     Move 1+ ι units down

                ‖C Reflect (in the default direction, right), leaving original intact

Спробуйте в Інтернеті! Посилання - це багатослівний код.


Мені це дуже подобається, +1; Також на виході OP використовується велика літера "O". (Не те, що це взагалі має значення лол)
Альберт Реншо

Якщо ви користуєтесь, ↘Oви можете перевести цикл від 0 до N включно, а це заощадить два байти негайно.
Ніл

@Neil Дякую! Крім того, це дуже стара публікація: P (і мені цікаво, чи варто використовувати новіші функції. Мабуть, ні?)
лише ASCII

Строго кажучи , я тільки врятував вас 1 байт до сих пір , як і інші два байта були ви замінити ⁺¹з . Однак тепер, коли ви перемістили з " ‖Cна", Oви можете зберегти ще один байт, записавши ↙OMι↓, тож я знову до двох байтів.
Ніл

Також ви забули оновити своє TIO-посилання. І технічно я вважаю, що зараз ми допускаємо новіші функції, але я не можу вимагати кредитів для цих байтів.
Ніл

6

С, 93 92

(Зауважте, хтось потрапив до 87 у коментарях)

y,n;f(s){for(y=0;y<=s;){printf("%*c%*c",s-y+1,79,y*2+1,79);for(n=++y;s+1-n&&n--;)puts("");}}

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


Читає:

y,n;f(s){
    for(y=0;y<=s;){
        printf("%*c%*c",s-y+1,79,y*2+1,79);
        for(n=++y;s+1-n&&n--;)puts("");
    }
}

Примітки:

Я можу згорнути обидві петлі на лише одну для циклу, повторивши загальну кількість виведених рядків, що задається формулою: n*-~n/2+1

y,n,r;f(s){
    for(r=s,y=n=0;r<s*-~s/2+1;)
        y==n?printf("%*c%*c",s-y+1,79,y*2+1,79),y=0,++n:r++,y++,puts("");
}

Але в кінцевому підсумку це навіть більше байтів, ніж просто використання двох окремих циклів


Ви можете зберегти один байт збільшенням sна початку, як це:y,n;f(s){++s;for(y=0;y<s;){printf("%*c%*c",s-y,79,y*2+1,79);for(n=++y;s-n&&n--;)puts("");}}
Steadybox

@Steadybox не компілюється для мене. Також я отримав 90 байт, коли порахував, що (після видалення символів пробілів)
Альберт Реншо

Все, що я робив, було додавати ++s;на початку, а потім змінювати y<=sна y<sта s-y+1в, s-yі s+1-nдо s-n, тому воно повинно складатись (і повинно бути 91 байт).
Steadybox

Здається, що в кодуванні блоку коду в моєму коментарі щось не так. Копіювання та вставлення коду з коментаря також не складеться для мене.
Steadybox




4

Python 2, 76 байт

x=input()
for i in range(x):print' '*(x-i),'O'+' '*i*2+'O'+'\n'*(i-x+1and i)

Досить просто. Це i-x+1and iполягає у запобіганні купі затяжних нових рядків.


Переміщаючи новий рядок до початку друку, як-от '\n'*(i-1)заощаджує 7 байт, уникаючи останніх нових рядків.
Емінья

4

MATL , 19 17 байт

Q:tqYsQ79Z?PtPv!c

Спробуйте в MATL Online! Або перевірити всі тестові випадки .

Пояснення

Q        % Implicitly input v. Add 1
:        % Push [1 2 ... v+1]
tq       % Duplicate and subtract 1: pushes [0 1 ... v]]
Ys       % Cumulative sum: gives [0 1 3 6 ...]
Q        % Add 1: gives [1 2 4 7 ...]
79       % Push 79 (ASCII for 'O')
Z?       % Create sparse matrix from column indices [1 2 3 4 ...],
         % row indices [1 2 4 7 ...], and data 79
P        % Flip vertically
tP       % Duplicate, flip vertically
v        % Concatenate the two matrices vertically
!        % Transpose
c        % Convert to char. Implicitly display. Char 0 is shown as space

4

05AB1E , 18 14 байт

Збережено 4 байти завдяки Аднану

ƒ¶N×'ONúRÂJ}.c

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

Пояснення

ƒ                   # for N in [0 ... input]
 ¶N×                # push N newlines
    'O              # push "O"
      Nú            # pad with N spaces in front
        RÂ          # reverese and create a reversed copy
          J         # join everything to a string
           }        # end loop
            .c      # pad lines until centered 

Для 14 байт: ƒ¶N×'ONúRÂJ}.c:)
Аднан

@Adnan Дякую! Я спробував .cз іншою версією, але тоді це не вийшло. Забув про спробу з цим і повністю забув, що úіснує :)
Emigna

Однозначно краще, ніж метод, який я вибрав, цікавий вертикальний підхід.
Magic Octopus Urn

4

JavaScript (ES6), 98 92 89 84 78 байт

(-20 байт завдяки Арнольду!)

f=(v,i=0)=>i>v?"":" "[r="repeat"](v-i)+0+" "[r](2*i)+0+`
`[r](i++<v&&i)+f(v,i)

Рекурсивне рішення. Це також мій перший коли - або відповідь на JavaScript, тому , будь ласка , бути ніжним! Я все ще вивчаю все це акуратною мовою, щоб запропонувати, тому поради з гольфу дуже вдячні. :)

Тест-фрагмент

Вам може знадобитися прокрутка, щоб побачити весь вихід.

f=(v,i=0)=>i>v?"":" "[r="repeat"](v-i)+0+" "[r](2*i)+0+`
`[r](i++<v&&i)+f(v,i)
<input id=i min=1 type=number><button onclick=alert(f(document.getElementById("i").value))>Submit</button>


Крім того, включаючи змінні всередині рядків backtick із ${}збереженням лише байтів, коли змінна частина оточена статичними частинами. Як такі, ці рядки завжди повинні починатися і закінчуватися статичними частинами.
Лука

@Arnauld Дякую за всі поради! Я дійсно ціную це! :)
Р. Кап

@Luke Дякую за пораду. Це стане в нагоді. :)
Р. Кап

Ви можете сміливо використовувати 0замість "0". Вони будуть примусові до рядків. А по другій думці: i++<v&&iнасправді на один байт коротше, ніж (i<v)*++i.
Арнольд

@Arnauld Ще раз дякую! :)
Р. Кап

3

RProgN 2 , 37 байт

x=0xR{y@xy-` *`o` y2**`o...2y{[` };};

Увійти з моєю доброю мовою перед тим, як підскочити належні гофровані язики.

Пояснив

x=              # Set 'x' to the input
0xR{            # For everything between the input and 0
    y@          # Set the iteration value to y, for this function only.
    xy-` *      # Subtract y from x, repeat the string " " that many times.
    `o          # Push an "o" to the stack.
    ` y2**      # Push 2*y " "'s to the stack
    `o          # Push another "o" to the stack
    ...         # Concatenate the parts of this string together, giving us the two balls.
    2y{[` };    # For all numbers between 2 and y, add a newline.
};              #

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


3

Сітківка, 29 19 байт

 ?
$.`$*¶$&$'O$`$`O

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

Здійснює введення в одинаковому режимі як пробіл. Порт моєї відповіді на JavaScript. Редагувати: Збережено 10 байт завдяки @ MartinEnder ♦


Я тільки чекаю, коли хтось придумає спина із сітківкою під назвою Ретсіна.
Тит

3

Баш , 76 байт

for((n=$1+1;--n;));{
yes ''|head -$n
r=$r${n}AO
t=›${n}BO$t
}
echo O${r}O$t

Працює лише в терміналі, оскільки він використовує послідовності відбору ANSI . представляє байт CSI ( 0x9b ).

Тестовий запуск

$ # The terminal's encoding must be set to ISO-8859-1.
$
$ xxd -g 1 arc.sh
0000000: 66 6f 72 28 28 6e 3d 24 31 2b 31 3b 2d 2d 6e 3b  for((n=$1+1;--n;
0000010: 29 29 3b 7b 0a 79 65 73 20 27 27 7c 68 65 61 64  ));{.yes ''|head
0000020: 20 2d 24 6e 0a 72 3d 24 72 9b 24 7b 6e 7d 41 4f   -$n.r=$r.${n}AO
0000030: 0a 74 3d 9b 24 7b 6e 7d 42 4f 24 74 0a 7d 0a 65  .t=.${n}BO$t.}.e
0000040: 63 68 6f 20 4f 24 7b 72 7d 4f 24 74              cho O${r}O$t
$
$ bash arc.sh 1
 OO
O  O
$ bash arc.sh 2
  OO
 O  O

O    O
$ bash arc.sh 3
   OO
  O  O

 O    O


O      O
$ bash arc.sh 4
    OO
   O  O

  O    O


 O      O



O        O

Ви можете використовувати sed $nqдля збереження байта.
зеппелін

На жаль, ні. Мені довелося б використовувати те, sed ${n}qщо довше.
Денніс

Argh, я бачу, ви можете зробити це sed $n\qнатомість, але це теж не має великого сенсу, як це було б те саме число байтів, як head!
зеппелін


3

R, 89 байт

a=2*v+3
x=matrix(" ",a,v^2+1)
for(k in 0:v)x[c(1-k,k+2)+v,k^2+1]="o"
x[a,]="\n"
cat(x,sep="")
  • Створіть матрицю пробілів (змінна a - ширина цієї матриці, заощадивши пару байтів)
  • Заповніть "o" s в необхідних місцях, працюючи зверху дуги вниз і назовні
  • Додайте новий рядок у кінці кожного рядка матриці
  • Згорніть матрицю вниз до однієї рядка і надрукуйте

Це моя перша спроба гри в гольф, коментарі вітаються ...


3

Рода , 53 52 байти

f n{seq 0,n|{|i|["
"*i," "*(n-i),"O"," "*i*2,"O"]}_}

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

Використання: main { f(5) }

Безгольова версія:

function f(n) {
    seq(0, n) | for i do
        push("\n"*i, " "*(n-i), "O", " "*i*2, "O")
    done
}

Чи можете ви використовувати буквальний новий рядок замість \nі зберегти 1 байт?
Kritixi Lithos

@KritixiLithos Це працює. Спасибі!
fergusq

2

Befunge, 75 73 байт

<vp00:&
1<-1_:v#\+55:g01\-g01g00" O"1\*2g01" O"1p0
#@_\:v>$$:!
1\,:\_^#:-

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

Перший рядок читає зі швидкістю, v і зберігає копію в пам'яті. Потім другий рядок відлічується від v до нуля, з індексом i , і на кожній ітерації висувається послідовність пар символів / довжини на стек.

Length  Character
-----------------
1       'O'
i*2     ' '
1       'O'
v-i     ' '
i       LINEFEED

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


2

Ява 8, 129 124 109 байт

Гольф:

v->{String s="",t="";for(int j,y=0;y<=v;++y){for(j=0;j<v;++j)s+=j<y?"\n":" ";s+="o"+t+"o";t+="  ";}return s;}

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

Безголівки:

public class DrawTheArcOfABall {

  public static void main(String[] args) {
    for (int i = 1; i < 6; ++i) {
      System.out.println(f(v -> {
        String s = "", t = "";
        for (int j, y = 0; y <= v; ++y) {
          for (j = 0; j < v; ++j) {
            s += (j < y ? "\n" : " ");
          }
          s += "o" + t + "o";
          t += "  ";
        }
        return s;
      } , i));
      System.out.println();
      System.out.println();
    }
  }

  private static String f(java.util.function.IntFunction<String> f, int v) {
    return f.apply(v);
  }
}


Для другого вкладеного циклу, я думаю, for(;j<v;++)це спрацювало б, бо в цей момент часу j==y. Крім того, ви можете видалити третю, додавши другу змінну рядка всередині основної для циклу String t="";(12) та t+=" ";(8) всередині першого вкладеного циклу. Тоді третя петля просто стаєs+="o"+t+"o";
nmjcman101

Крім того, ви можете поєднати перші два вкладені петлі, for(j=0;j<v;++j)s+=j<y?"\n":" ";хоча я не впевнений, як це відбувається з моїм попереднім коментарем проt
nmjcman101

Ви можете форматувати t=""поряд з на початку, а потім додати t+=" "кожну петлю навколо після ви робитеs+="o"+t+"o"
nmjcman101


2

VBA, 124 112 85 88 66 63 59 байт

For i=0To[A1]:?Space([A1]-i)"O"Space(2*i)"O"String(i,vbCr):Next

Збережено 29 байт загалом завдяки Тейлор Скотт

Це потрібно запустити в негайному вікні VBA і надрукувати результат в тому ж самому.

Розширений / відформатований, він стає:

For i=0 To [A1]
   Debug.Print Space([A1]-i) & "O" & Space(2*i) & "O" & String(i,vbCr)
Next

(Виявляється, що з'єднання в команді print друкується автоматично без оператора.)


b & s &Попередження про простори!
CalculatorFeline

Я спробував, і це помилилося в перший раз. Повернувшись назад, я зрозумів, що вона розшириться, b &s &Stringале ні b&s&String. Крім того, спочатку я подумав, що ти маєш намір використовувати Spaceфункцію, яку я повинен повністю мати, і це в результаті зберегло більше байтів.
Інженер Тост

Ви можете конденсувати for i=0 To vі debug.? bдо, for i=0To vі Debug.?bвідповідно для -2байтів. І лише щоб ви знали, спільна думка спільноти полягає в тому, що для мов з автоматичним форматуванням ви можете розраховувати до її автоматичного форматування, тобто після внесення цих змін вам слід мати кількість байтів у 85 байт
Тейлор Скотт,

По-друге, це фрагмент - не функція чи підпрограма; тому це не є правильним рішенням. Я вважаю, що ви можете це виправити, перетворивши його на функцію негайного вікна Excel VBA та взявши вхід з [A1]( v=[A1]) Крім того, я не думаю, що вам насправді потрібна sзмінна.
Тейлор Скотт

1
@TaylorScott Це здається очевидним поліпшенням ретроспективи, але я не знав, що конкатенація не потребує оператора в безпосередньому вікні. Це врятує мене кілька байтів у майбутньому. Мені довелося додати a ;до кінця команди print, тому що вона за замовчуванням додавала додатковий розрив рядка. Спасибі!
Інженер Тост


1

Желе , 17 16 байт

‘Ḷ+\Ṛ⁶ẋ;€”Om0z⁶Y

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

Як?

‘Ḷ+\Ṛ⁶ẋ;€”Om0z⁶Y - Main link: v         e.g. 3
‘                - increment: v+1            4
 Ḷ               - lowered range             [0,1,2,3]
  +\             - reduce with addition      [0,1,3,6]
    Ṛ            - reverse                   [6,3,1,0]
     ⁶           - a space                   ' '
      ẋ          - repeat (vectorises)       ['      ','   ',' ','']
       ;€        - concatenate each with
         ”O      -     an 'O'                ['      O','   O',' O','O']
           m0    - concatenate reflection    ['      O','   O',' O','O','O','O ','O   ','O      ']
             z⁶  - transpose with space fill ['   OO   ','  O  O  ','        ',' O    O ','        ','        ','O      O']
               Y - join with line feeds      ['   OO   \n  O  O  \n        \n O    O \n        \n        \nO      O']
                 - implicit print

1

PHP, 76 байт

for(;$argn>=0;$s.="  ")echo($r=str_repeat)("
",$i++),$r(" ",$argn--),o,$s,o;

Запустіть echo <v> | php -nR '<code>'або випробуйте його в Інтернеті .

петлі $argnвниз від вводу до 0і $iвід 0;
відбитки - у такому порядку - у кожній ітерації

  • $i нові рядки (немає в першій ітерації)
  • ліва підкладка: $argnпробіли
  • ліва куля: o
  • внутрішня підкладка: 2*$iпробіли
  • правильний м'яч: o

1

V , 23 19 байт

2éoÀñYço/^2á O
HPJ>

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

Поясніть

2éo            " Insert two 'o's
   Àñ          " <Arg> times repeat
     Y         " Yank the current (top) line.  This is always '\s*oo'
      ço/      " On every line that matches 'o'
         ^     " Go to the first non-whitespace character (the 'o')
          2á   " Append two spaces (between the two 'o's
             O " Add a blank line on top of the current one
H              " Go to the first line
 P             " Paste in front ('\s*oo')
  J            " Join this line with the blank line immediately after it
   >           " Indent once

1

JavaScript (ES6), 87 байт

f=
n=>' '.repeat(n+1).replace(/./g,"$`#$'O$`$`O").replace(/ *#/g,s=>[...s].fill``.join`
`)
<input type=number min=0 oninput=o.textContent=f(+this.value)><pre id=o>

Нерецидивний розчин. Вимога індексування дратувала, як у вищезазначеному, так і в наступному 62-байтному (не знаю, чи призведе це до коротшого порту Retina) рекурсивного рішення:

f=n=>~n?` `.repeat(n)+`OO`+f(n-1).replace(/^ *O/gm,`
$&  `):``


0

Зіставлено, 67 63 байти

args 0#1+:@x:>{!n x\-1-' '*'O'+n 2*' '*+'O'+x 1-n!=n*LF*+out}"!

Початкова спроба, 67 байт

args 0# :@v 1+2*:>[:v:+1+\-2/*' '*'O'+''split]"!fixshape tr rev out

Повна програма. Породжує щось на кшталт:

('O'
 ' ' 'O'
 ' ' 'O'
 'O')

Який є вкладений, транспонований, перетворений та виведений.


0

Пакетна, 163 байти

@set l=@for /l %%i in (1,1,%1)do @call
@set s=
%l% set s= %%s%%
@set t=
%l%:c&for /l %%j in (2,1,%%i)do @echo(
:c
@echo %s%O%t%O
@set s=%s:~1%
@set t=  %t%

0

Рубін, 52 байти

->x{(0..x).map{|a|$><<$/*a+' '*(x-a)+?O+' '*a*2+?O}}

Немає останнього нового рядка (дозволено правилами: " щонайменше один зворотний рядок ")


0

AHK, 93 байти

m=0
n=1
f=%1%-1
Loop,%1%{
r=%r%{VK20 %f%}O{VK20 %m%}O{`n %n%}
m+=2
n++
f--
}
FileAppend,%r%,*

Якби я міг зрозуміти, як зробити математику всередині повторюваних натискань клавіш, це було б чудово.
- VK20прирівнюється до пробілу
- FileAppendвиводиться, stdoutякщо ім'я файлу*



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