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


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
Мукул Кумар

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 байта).


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.


Я должен спросить ... 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 слов).


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


Можете ли вы расширить демо до чуть больше 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
Часть 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)


1

питон - 39

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

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


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

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

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.