Рассчитать все квадраты до х, используя только сложение и вычитание

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
Coaumdio
источник
1
эта логика отлично! Вы заслуживаете +1
Мукул Кумар
5

GolfScript, 17 символов

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

Использование (см. Также примеры онлайн ):

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

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

Говард
источник
ХОРОШО; как это работает?
Зубная щетка
@toothbrush ,принимает входные данные и преобразует их в массив [0 1 ... n-1]. Затем *внедряет данный блок кода в массив. Этот блок сначала удваивает текущий item ( .+), вычитает один ( (), а затем добавляет предыдущий результат 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 байта).

mackthehobbit
источник
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
        ];

Редактирование:

Хайко Обердиек
источник
Я не вижу причин, почему вы должны назвать свой саб. IOW "sub {map {$ a + = $ _ + $ _- 1} 1..shift}" кажется мне законным и спасает вас от двух символов.
Скибрянски
@skibrianski: анонимная функция также является функцией. Недостатком является то, что вызов функции немного сложнее.
Хайко Обердик
Да, но это на звонилке. Есть записи на других языках, которые определяют анонимные подпрограммы, поэтому я думаю, что вы в безопасности =)
skibrianski
И вы можете сохранить еще 2 символа, используя 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.

mt0
источник
Я должен спросить ... i+++iв конце ...?
WallyWest
2
k+=i+++iэто то же самое, k += i + (++i)что и то, что k+=i+i+1следует заi=i+1
MT0
О, это гений ... Я должен реализовать это в моем следующем Codegolf, если нужно! :)
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» не является умножением в Юлии? Вместо этого вы можете сказать х + х, что обойдется вам всего в один байт.
Гленн Рандерс-Персон
Вы правы (не заметили), отредактировано.
КПК
Я не знаком (пока) с Джулией, но посмотрел ее в онлайн-руководстве по адресу docs.julialang.org/en/release-0.2 и обнаружил, что «Числовые буквенные коэффициенты: чтобы сделать обычные числовые формулы и выражения более понятными, Джулия разрешает переменные» непосредственно предшествует числовой литерал, подразумевающий умножение ". Так что да, 2х - это умножение.
Гленн Рандерс-Персон
2

С ++ 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
Этот код имеет неопределенное поведение.
Kerrek SB
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 слов).

mackthehobbit
источник
2

Haskell

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].

PyRulez
источник
Можете ли вы расширить демо до чуть больше 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]
Flonk
источник
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
Часть Arrow Function спецификации 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)

blabla999
источник
1

питон - 39

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

Заменить 5на любое значение. Какие-либо предложения?

qwr
источник
1

Баш - 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 символов) с APL NGN: 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;}
Rik
источник
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элемента th.

Раджеш
источник
Вы пытались удалить пробелы между int[]и sq? Я не знаю C #, но я думаю, что это должно работать.
user12205
Нет, это не сработает. Первый int [] - это тип возвращаемого значения метода "sq". Я могу уменьшить имя метода до «s» :)
Раджеш
Я имею в виду использование int[]sqвместо int[] sqи int[]resвместо int[] res. Это поможет вам сохранить два символа, и я не получил никаких ошибок компиляции с этим. Также вы должны использовать одиночные символьные идентификаторы для sqи resкак вы предложили.
user12205
кажется, что с вашим ответом что-то не так
user12205 26.02.14
Для отступа кода с 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

Python - 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
nneonneo
источник
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 
soapergem
источник
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
Майкл
источник