Обчисліть усі квадрати до x, використовуючи лише додавання і віднімання


11

Мета - обчислити всі квадрати до xдодавання та віднімання.

Правила:

  1. Код повинен бути функцією, яка приймає загальну кількість квадратів для генерації та повертає масив, що містить усі ці квадрати.
  2. Ви можете НЕ використовувати рядки, структури, множення, ділення, або вбудовані функції для обчислення квадратів.
  3. Можна використовувати лише масиви, цілі числа (цілі числа), додавання, віднімання. Жодних інших операторів заборонено!

Це питання з , тому найкоротший код у байтах виграє!


Це, по суті, найбільш оптимізований алгоритм збільшення квадратів - або, принаймні, отримає майже однакові відповіді.
Пітер Тейлор

2
@PeterTaylor Ні, це не те саме, як це для найбільш оптимізованого алгоритму збільшення квадратів, але моє питання вимагає лише додавання і віднімання.
Зубна щітка

Що це те саме. Як свідок: теперішня відповідь на це питання робить точно так само, як і переважна більшість відповідей на попереднє питання.
Пітер Тейлор

@PeterTaylor Я можу бути упередженим, але я дійсно не думаю, що це зовсім не те саме.
Зубна щітка

3
На це запитання вже можуть бути відповіді в іншому місці, але це не робить запитання дублікатом іншого питання.
Blacklight Shining

Відповіді:



6

C, 55 52 байти

int s(int n,int*r){for(int i=0,j=-1;n--;*r++=i+=j+=2);}

просто підсумовує непарні числа

  • n: кількість квадратів для обчислення
  • r: вихідний масив для зберігання результатів
  • j: приймає послідовні значення 1, 3, 5, 7, ...
  • i: збільшується jна кожну ітерацію

Редагувати

4 символи можна зберегти за допомогою неявного int-оголошення (> C99), але це коштує 1 знака, оскільки forініціалізатори не можуть містити декларацію в> C99. Потім код стає

s(int n,int*r){int i=0,j=-1;for(;n--;*r++=i+=j+=2);}

Використання

void main() {
    int r[20];
    s(20, r);
    for (int i = 0; i < 20 ; ++i) printf("%d\n", r[i]);
}  

Вихідні дані

1
4
9
16
25
36
49
(...)
361
400

1
що логіка відмінна! ви заслуговуєте +1
Mukul Kumar

5

GolfScript, 17 символів

{[,{.+(1$+}*]}:F;

Використання (див. Також приклади в Інтернеті ):

10 F     # => [0 1 4 9 16 25 36 49 64 81]

Примітка: * це цикл, а не оператор множення.


ДОБРЕ; як це працює?
Зубна щітка

@toothbrush ,приймає вхід і перетворює його в масив [0 1 ... n-1]. Потім *вводить даний масив коду в масив. Цей блок спочатку подвоює поточний елемент ( .+) віднімає один ( (), а потім додає попередній результат 1$+(іншими словами, додайте 2j-1до попереднього квадратного числа). []додає все, щоб повернути новий масив.
Говард

Чудово! Я не знаю GolfScript, тому я задумався, як це працює.
Зубна щітка

5

Пакет Windows, 115 байт

setlocal enabledelayedexpansion&for /l %%i in (1 1 %1)do (set a=&for /l %%j in (1 1 %%i)do set /a a+=%%i
echo.!a!)

Це слід помістити у пакетний файл, а не запускати з cmd, і він виводить список на консоль. Для першого аргументу командного рядка потрібно створити кількість квадратів. Здебільшого він використовує &замість нових рядків, однако все ще потрібен, але він рахується як два байти.

Для цього потрібно включити розширене змінне розширення, це можна зробити cmd /v:on. Якщо припустити, що це не так, додатково setlocal enabledelayedexpansion&було потрібно додатково (без цього сценарій становить 83 байти).


4

Хаскелл - 30

f n=scanl1(\x y->x+y+y-1)[1..n]

Для цього використовується той факт, що (n+1)^2=n^2+2n+1


4

Perl, 27 байт

sub{map{$a+=$_+$_-1}1..pop}

Математика:

Математика

Сценарій виклику функції для друку 10 квадратів:

#!/usr/bin/env perl
$square = sub{map{$a+=$_+$_-1}1..pop};
use Data::Dumper;
@result = &$square(10);
print Dumper \@result;

Результат:

$VAR1 = [
          1,
          4,
          9,
          16,
          25,
          36,
          49,
          64,
          81,
          100
        ];

Зміни:

  • Анонімна функція (−2 байти, спасибі skibrianski )
  • popзамість shift(−2 байти, спасибі skibiranski )

Я не бачу причин, чому вам потрібно називати свій суб. IOW "sub {map {$ a + = $ _ + $ _- 1} 1..shift}" здається мені законним, і економить вам дві характеристики.
скибрянський

@skibrianski: Анонімна функція також є функцією. Мінус полягає в тому, що виклик функції є дещо громіздкішим.
Хайко Обердік

Правильно, але це на абонента. Є записи іншими мовами, які визначають анонімні абонементи, тому я думаю, що ви безпечні =)
skibrianski

І ви можете зберегти ще два знаки, використовуючи pop () замість shift (), оскільки є лише один аргумент.
скибрянський

@skibrianski: Правильно, дякую.
Хайко Обердік

4

JavaScript - 32 символи

for(a=[k=i=0];i<x;)a[i]=k+=i+++i

Припускає, що xіснує змінна і створює масив aквадратів для значень 1..x.

ECMAScript 6 - 27 символів

b=[f=i=>b[i]=i&&i+--i+f(i)]

Виклик f(x)заповнить масив bквадратами для значень 0..x.


Я повинен запитати ... i+++iв кінці ...?
WallyWest

2
k+=i+++iте саме, k += i + (++i)що є тим самим, k+=i+i+1за яким слідуєi=i+1
MT0

О, це геній ... Я повинен це реалізувати у своєму наступному кодовому гольфі, якщо потрібно! :)
WallyWest

Ви можете зберегти один символ, перемістивши декларацію функції всередину масиву (наприклад b=[f=i=>b[i]=i&&i+--i+f(i)]).
Зубна щітка

Спасибі - також збережено одного символу на верхній відповіді, переміщаючи речі навколо, щоб видалити крапку з двокрапкою.
MT0

4

Юлія - ​​33 роки

Будь-яке квадратне число можна записати підсумком непарних чисел:

julia> f(x,s=0)=[s+=i for i=1:2:(x+x-1)];f(5)
5-element Array{Int64,1}:
  1
  4
  9
 16
 25

Привіт, ласкаво просимо на CG.se! Приємна, лаконічна відповідь. Ніколи не чув про Юлію, але це виглядає інтригуюче.
Джонатан Ван Матре

Хіба не "2x" множення у Джулії? Ви можете сказати натомість x + x, що обійдеться вам всього в один байт.
Гленн Рендерс-Персон

Ви праві (не помітили), відредаговані.
КПК

Я не знайомий (поки) з Джулією, але переглянув це в онлайн-посібнику на docs.julialang.org/en/release-0.2 і виявив, що "Числові літературні коефіцієнти: Щоб зробити загальні числові формули та вирази зрозумілішими, Юлія дозволяє змінні безпосередньо перед цим числовим буквалом, що передбачає множення ". Так що так, 2х - це множення.
Гленн Рендерс-Персон

2

C ++ 99 81 78 80 78

int* f(int x){int a[x],i=1;a[0]=1;while(i<x)a[i++]=a[--i]+(++i)+i+1;return a;}  

моя перша спроба в коді-гольф

цей код заснований на
a = 2 xn - 1,
де n - кількість термінів і a - n- й член у наступних рядах
1, 3, 5, 9, 11, 13, .....
сума перших 2 доданків = 2 у квадраті

сума перших 3 доданків = 3 квадрата
і так далі ...


2
Я думаю, ви можете зняти дужки {}після forциклу, оскільки є лише одне твердження. Це може зменшити кількість ваших знаків на 2
user12205

1
Якщо ви оголошуєте масиви непостійного розміру в якійсь іншій функції, ніж main (), це прийнятно
Mukul Kumar

1
Цей код не визначений.
Керрек СБ

1
і повертає вказівник на дані про стек, знищений під час повернення.
VX

1
@MukulKumar addition, subtraction, я використовую лише ті
mniip

2

DCPU-16 Асамблея (90 байт)

Я написав це на зборах для вигаданого процесора, бо чому б ні?

:l
ADD I,1
SET B,0
SET J,0
:m
ADD J,1
ADD B,I
IFL J,I
SET PC,m
SET PUSH,B
IFL I,X
SET PC,l

Очікується, що їх число буде в реєстрі X, а в інших регістрах очікується 0. Отримати результати будуть висунуті до стеку, він порушиться, коли він досягне 65535 завдяки 16-бітній архітектурі. Ви можете додати SUB PC, 1до кінця тест, щоб перевірити його. Складено, програма повинна мати 20 байт (10 слів).


2

Хаскелл

f x=take x [iterate (+y) 0 !! y | y<- [0..]]

Це в основному винаходить множення, використовує його власне і відображає їх по всіх числах. f 10= [0,1,4,9,16,25,36,49,64,81]. Також f 91= [0,1,4,9,16,25,36,49,64,81,100,121,144,169,196,225,256,289,324,361,400,441,484,529,576,625,676,729,784,841,900,961,1024,1089,1156,1225,1296,1369,1444,1521,1600,1681,1764,1849,1936,2025,2116,2209,2304,2401,2500,2601,2704,2809,2916,3025,3136,3249,3364,3481,3600,3721,3844,3969,4096,4225,4356,4489,4624,4761,4900,5041,5184,5329,5476,5625,5776,5929,6084,6241,6400,6561,6724,6889,7056,7225,7396,7569,7744,7921,8100].


Чи можете ви розширити демонстрацію на трохи більше 10?
Гленн Рендерс-Перхсон

2

Хаскелл, 34/23

n#m=m+n:(n+2)#(m+n)
f n=take n$1#0

або, якщо імпорт нормальний:

f n=scanl1(+)[1,3..n+n]

Вихід:

λ> f 8
[1,4,9,16,25,36,49,64]

1

Javascript 47

function f(n,a){return a[n]=n?f(n-1,a)+n+n-1:0}

r=[];f(12,r);console.log(r) повертає:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144]


Чудово! У ECMAScript 6: f=(n,a)=>a[n]=n?f(n-1,a)+n+n-1:0.
Зубна щітка

1
Я дійсно не можу чекати, коли ECMAScript 6 дійсно увійде в основне використання. Це було б ідеальним приводом, щоб навчитися цьому.
Іся Медоуз

1
Частина функції функції стрілки специфікації ECMAScript 6 перебуває у FireFox з версії 22.
MT0,

1

Smalltalk, 52

f:=[:n||s|(s:=1)to:n collect:[:i|x:=s.s:=s+i+i+1.x]]

Повертає новий масив (тобто не заповнює і не додає до існуючого).

дзвінок:

значення f: 10

-> # (1 4 9 16 25 36 49 64 81 100)


1

пітон - 39

a=0
for i in range(5):a+=i+i+1;print(a)

Замініть 5будь-яким значенням. Будь-які пропозиції?


1

Bash - 92 85 62 61 59 57

declare -i k=1;for((i=0;i++<$1;k+=i+i+1));do echo $k;done

Результат:

$ ./squares.sh 10
1
4
9
16
25
36
49
64
81
100

Редагувати: Я замінив внутрішній цикл алгоритмом з рішення Haskell @ mniip.


1

Той самий метод, що і вище, в APL та J:

APL: F←{+\1+V+V←¯1+⍳⍵}(17 символів) працює з більшістю варіантів APL (спробуйте тут )

і навіть менше (всього 14 символів) з NGN APL: F←{+\1+V+V←⍳⍵}(див. тут )

J: f=:+/\@(>:@+:@:i.)(18 символів)

редагувати: краще рішення в APL: F←{+\¯1+V+V←⍳⍵}(15 символів)


1

C # (82)

int[] s(int n){int i,p=0;var r=new int[n];while(i<n){p+=i+i+1;r[i++]=p;}return r;}

1

C # - 93

int[]s(int l){int[]w=new int[l];while(l>=0){int i=0;while(i<l){w[l-1]+=l;i++;}l--;}return w;}

При [1,4,9,16,25,36...]виклику з іншого методу того ж класу поверне масив - , до- lго елемента.


ви намагалися видалити пробіли між int[]і sq? Я не знаю C #, але я думаю, що це має працювати.
користувач12205

Ні, це не працює. Перший int [] - тип повернення методу "sq". Я можу зменшити ім'я методу до "s" :)
Раджеш,

Я маю на увазі використання int[]sqзамість int[] sqі int[]resзамість int[] res. Це допомагає вам зберегти дві символи, і я не отримав жодних помилок компіляції з цим. Також слід використовувати окремі ідентифікатори символів для sqта, resяк ви запропонували.
користувач12205

здається, що у вашій відповіді щось не так
user12205

Код відступу з 4 пробілами, щоб помістити його в блок-код з шрифтом монопростір.
luser droog

1

Фортран II | IV | 66 | 77, 134 122 109 105

  SUBROUTINES(N,M)
  INTEGERM(N)
  K=0
  DO1I=1,N
  K=K+I+I-1
1 M(I)=K
  END

Редагувати: видалено внутрішній цикл і замість цього використовується алгоритм Haskell @ mniip.

Редагувати: Перевірено, що підпрограма та драйвер є дійсними Fortran II та IV

Водій:

  INTEGER M(100)
  READ(5,3)N
  IF(N)5,5,1
1 IF(N-100)2,2,5
2 CALLS(N,M)
  WRITE(6,4)(M(I),I=1,N)
3 FORMAT(I3)
4 FORMAT(10I6)
  STOP  
5 STOP1
  END

Результат:

$ echo 20 | ./a.out
   1     4     9    16    25    36    49    64    81   100
 121   144   169   196   225   256   289   324   361   400

@mniip, дякую, я замінив свій внутрішній цикл вашим кодом.
Гленн Рендерс-Персон

1

Пітон - 51

Тут я визначаю функцію відповідно до вимог правил.

Використання sumнепарних чисел:

f=lambda n:[sum(range(1,i+i+3,2))for i in range(n)]

Для цього використовується лише sum(вбудований, який виконує додавання) та range(вбудований, який створює масиви за допомогою додавання). Якщо ви заперечуєте проти sum, ми можемо це зробити за допомогою reduce:

def g(n):v=[];reduce(lambda x,y:v.append(x) or x+y,range(1,i+i+3,2));return v

1

PHP, 92 байти

Для цього, звичайно, має бути включена опція "короткі теги" (щоб спочатку стригти 3 байти).

<? $x=100;$a=1;$r=0;while($r<=$x){if($r){echo"$r ";}for($i=0,$r=0;$i<$a;$i++){$r+=$a;}$a++;}

Вихід:

1 4 9 16 25 36 49 64 81 100 

1

Четверте - 48 байт

: f 1+ 0 do i 0 i 0 do over + loop . drop loop ;

Використання:

7 f

Вихід:

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