Обратная гипотеза Коллатца

13

Я думаю, что гипотеза Коллатца уже известна. Но что, если мы изменим правила?

Начните с целого числа n> = 1.

Повторите следующие шаги:

Если n четное , умножьте его на 3 и добавьте 1.

Если n нечетно , вычтите 1 и разделите его на 2.

Стоп, когда он достигает 0

Распечатайте повторяющиеся числа.

Тестовые случаи:

 1        => 1, 0
 2        => 2, 7, 3, 1, 0
 3        => 3, 1, 0
10        => 10, 31, 15, 7, 3...
14        => 14, 43, 21, 10, ...

Правила:

  • Эта последовательность не работает для большого числа чисел, потому что она входит в бесконечный цикл. Вам не нужно обрабатывать эти случаи. Достаточно только распечатать приведенные выше контрольные примеры.

  • Я предложил вычесть 1 и разделить на два, чтобы получить действительное целое число для продолжения, но это не требуется для вычисления таким образом. Вы можете разделить на 2 и привести к целому числу или любым другим методам, которые дадут ожидаемый результат.

  • Вам также необходимо распечатать начальный ввод.

  • Выходные данные не должны быть отформатированы как контрольные примеры. Это было просто предложение. Тем не менее, повторный порядок должен соблюдаться.

  • Наименьший код выигрывает.

Эдуардо Хофель
источник
9
Поскольку это ваш третий вопрос за много часов, я бы порекомендовал вам проверить Песочницу , место, где мы обычно публикуем черновики вопросов для обратной связи, и убедиться, что они не являются дубликатами.
Caird Coneheringaahing
Спасибо @cairdcoinheringaahing. Я не знал об этой странице.
Эдуардо Хофел
Должны ли мы распечатать 0в конце?
flawr
2
Возможно, вы захотите расширить два последних тестовых примера, поскольку они не такие длинные
Джо Кинг,
3
@JoKing Я сжал его, потому что он повторяет вывод из других строк. В точке, где вы достигнете 3 , он будет иметь тот же результат, что и вы, начиная с него. То же самое относится к 10 или любому другому номеру.
Эдуардо Хофел

Ответы:

5

Perl 6 , 30 байт

{$_,{$_%2??$_+>1!!$_*3+1}...0}

Попробуйте онлайн!

Блок анонимного кода, который возвращает последовательность.

Объяснение:

{$_,{$_%2??$_+>1!!$_*3+1}...0}
{                            }   # Anonymous code block
   ,                     ...     # Define a sequence
 $_                              # That starts with the given value
    {                   }        # With each element being
     $_%2??     !!               # Is the previous element odd?
           $_+>1                 # Return the previous element bitshifted right by 1
                  $_*3+1         # Else the previous element multiplied by 3 plus 1
                            0    # Until the element is 0
Джо Кинг
источник
2

Python 2, 54 52 44 байта

n=input()
while n:print n;n=(n*3+1,n/2)[n%2]

-2 байта благодаря мистеру Xcoder

Там, безусловно, должен быть более быстрый путь. Как ни странно, когда я попробовал лямбду, это был тот же самый счет. Я, вероятно, галлюцинации.

Попробуйте онлайн!

Quintec
источник
-2 байта
г-н Xcoder
@ Mr.Xcoder Ах, спасибо.
Quintec
1
50 байтов
Джо Кинг,
Хотя 0теперь это не является обязательным, так что короче, чтобы избавиться от второгоprint
Джо Кинг
Действительно, теперь вы можете сделать это в 44 году
Mr. Xcoder
2

Haskell , 76 69 61 56 байт

Я чувствую, что это слишком долго. Вотl создается бесконечный список последовательности обратных коллатцов, а анонимная функция в первой строке просто обрезает ее в нужном месте.

Спасибо за -5 байтов @ janrjanJohansen!

fst.span(>0).l
l r=r:[last$3*k+1:[div k 2|odd k]|k<-l r]

Попробуйте онлайн!

flawr
источник
Здесь нет отрицательных чисел, поэтому (>0)должно хватить. Также есть oddфункция.
Орджан Йохансен
@ ØrjanJohansen Большое спасибо!
августа
2

05AB1E , 15 14 байтов

[Ð=_#Èi3*>ë<2÷

-1 байт благодаря @MagicOctopusUrn .

Попробуйте онлайн.

Объяснение:

[             # Start an infinite loop
 Ð            #  Duplicate the top value on the stack three times
              #  (Which will be the (implicit) input in the first iteration)
  =           #  Output it with trailing newline (without popping the value)
   _#         #  If it's exactly 0: stop the infinite loop
     Èi       #  If it's even:
       3*     #   Multiply by 3
         >    #   And add 1
      ë       #  Else:
       <      #   Subtract 1
        2÷    #   And integer-divide by 2
Кевин Круйссен
источник
[Ð=_#Èi3*>ë<2÷с =вместо D,.
Волшебная Осьминог Урна
@MagicOctopusUrn Ах, это было очень плохо забыть .. Спасибо! :)
Кевин Круйссен
2

JAEL , 18 байт

![ؼw>î?èÛ|õÀ

Попробуйте онлайн!

Эдуардо Хофель
источник
1
Ваша постоянная ссылка, похоже, не работает. Программа просто печатает ввод и останавливается.
Денис
Да, ты прав. Я попрошу «их» вытащить последнюю версию: P
Эдуардо Хофел
Я добавил JAEL в список языков игры в гольф . Пожалуйста, дайте мне знать, если я получил какую-либо информацию неправильно :-)
ETHproductions
@ETHproductions Большое спасибо: D Я думаю, что могу сказать, что специальность - это пакет утилит, который помогает программисту сжимать код, но это только я пытаюсь сделать это.
Эдуардо Хофел
1

Wolfram Language (Mathematica) , 35 байт

0<Echo@#&&#0[3#+1-(5#+3)/2#~Mod~2]&

Попробуйте онлайн!

0<Echo@# && ...&Оценка короткого замыкания: она печатает ввод #, проверяет, является ли он положительным, и, если да, оценивает .... В этом случае ...есть #0[3#+1-(5#+3)/2#~Mod~2]; так как #0(нулевой слот) является самой функцией, это рекурсивный вызов 3#+1-(5#+3)/2#~Mod~2, который упрощает, 3#+1когда #четное, а (#-1)/2когда #нечетное.

Миша лавров
источник
1

PowerShell, 53 52 байта

param($i)for(;$i){$i;$i=(($i*3+1),($i-shr1))[$i%2]}0

Попробуйте онлайн!

Редактировать:
-1 байт благодаря @mazzy

Дж. Бергманн
источник
Вы можете попробовать for(;$i)вместо этогоwhile($i)
mazzy
1

Эмоджикод 0,5 , 141 байт

🐖🎅🏿🍇🍮a🐕😀🔡a 10🔁▶️a 0🍇🍊😛🚮a 2 1🍇🍮a➗a 2🍉🍓🍇🍮a➕✖️a 3 1🍉😀🔡a 10🍉🍉

Попробуйте онлайн!

🐖🎅🏿🍇
🍮a🐕      👴 input integer variable 'a'
😀🔡a 10      👴 print input int
🔁▶️a 0🍇      👴 loop while number isn’t 0
🍊😛🚮a 2 1🍇     👴 if number is odd
🍮a➗a 2       👴 divide number by 2
🍉
🍓🍇      👴 else
🍮a➕✖️a 3 1   👴 multiply by 3 and add 1
🍉
😀🔡a 10     👴 print iteration
🍉🍉
X1M4L
источник
1

MathGolf , 12 байт

{o_¥¿½É3*)}∟

Попробуйте онлайн!

объяснение

{             Start block of arbitrary length
 o            Output the number
  _           Duplicate
   ¥          Modulo 2
    ¿         If-else with the next two blocks. Implicit blocks consist of 1 operator
     ½        Halve the number to integer (effectively subtracting 1 before)
      É       Start block of 3 bytes
       3*)    Multiply by 3 and add 1
          }∟  End block and make it do-while-true
maxb
источник
Я добавил MathGolf в список гольф- лангов - не стесняйтесь поправлять меня, если я ошибаюсь :-)
ETHproductions
Спасибо за добавление! Все выглядит правильно для меня.
maxb
1

машинный код x86, 39 байт

00000000: 9150 6800 0000 00e8 fcff ffff 5958 a901  .Ph.........YX..
00000010: 0000 0074 04d1 e8eb 066a 035a f7e2 4009  ...t.....j.Z..@.
00000020: c075 dec3 2564 20                        .u..%d 

Сборка (синтаксис NASM):

section .text
	global func
	extern printf
func:					;the function uses fastcall conventions
	xchg eax, ecx			;load function arg into eax
	loop:
		push eax
		push fmt
		call printf	;print eax
		pop ecx
		pop eax
		test eax, 1	;if even zf=1
		jz even		;if eax is even jmp to even
		odd:		;eax=eax/2
			shr eax, 1
			jmp skip
		even:		;eax=eax*3+1
			push 3
			pop edx
			mul edx
			inc eax
		skip:
		or eax, eax
		jne loop	;if eax!=0, keep looping
	ret			;return eax
section .data
	fmt db '%d '

Попробуйте онлайн!

Logern
источник
1

Р , 66 61 байт

-5 байтов благодаря Роберту С. в консолидации ifelse ifи удалении скобок, и от x! = 0 до x> 0

print(x<-scan());while(x>0)print(x<-`if`(x%%2,(x-1)/2,x*3+1))

вместо того

print(x<-scan());while(x!=0){print(x<-ifelse(x%%2,(x-1)/2,x*3+1))}

Попробуйте онлайн!

Sumner18
источник
1
61 байт
Роберт С.
0

perl -Minteger -nlE, 39 байт

{say;$_=$_%2?$_/2:3*$_+1 and redo}say 0

источник
0

Добавить ++ , 38 35 33 байта

D,f,@:,d3*1+$2/iA2%D
+?
O
Wx,$f>x

Попробуйте онлайн!

Как это устроено

Во-первых, мы начинаем с определения функции е(Икс), который принимает один аргумент, выполняет перевернутую операцию Коллатца на Иксзатем выводит результат. То есть,

е(Икс)знак равно{Иксдаже,3Икс+1Иксстранно,Икс2

В режиме функции Add ++ использует модель стековой памяти, в противном случае используются переменные. При расчетее(Икс)стек изначально выглядит так Sзнак равно[Икс],

Затем мы дублируем это значение ( d), чтобы получитьSзнак равно[Икс,Икс], Затем мы получаем первый возможный вариант,3Икс+1( 3*1+), поменяйте местами два верхних значения, затем рассчитайтеИкс2, оставляя Sзнак равно[3Икс+1,Икс2],

Далее мы нажимаем Икс в Sи вычислить бит Икс т.е. Икс%2, где a%бобозначает остаток при деленииa по б, Это оставляет нас сSзнак равно[3Икс+1,Икс2,(Икс%2)], Наконец, мы используем, Dчтобы выбрать элемент по индексу, указанному(Икс%2), Если это0мы возвращаем первый элемент т.е. 3Икс+1в противном случае мы возвращаем второй элемент, Икс2,

Это завершает определение е(Икс)Однако мы еще не реализовали это на практике. Следующие три строки перешли из функционального режима в режим ванили, где мы оперируем переменными. Чтобы быть более точным, в этой программе мы оперируем только одной переменной, активной переменной , представленной буквой x. Тем не мение,x может быть опущен в командах, где это явно другой аргумент.

Например, +?идентично x+?и присваивает входные данные x, но, как xи активная переменная , оно может быть опущено. Затем мы выводим x, затем весь цикл while, который выполняется до тех пор, покаИкс0, Цикл очень простой, состоящий из одного оператора: $f>x. Все это работаете(Икс), затем назначьте это x, обновляя xна каждой итерации цикла.

Кэрд
источник
Просто чтобы понять: является ли строка разрыва частью кода? Или это только для лучшего объяснения? Я действительно не знаю этот язык.
Эдуардо Хофел
@EduardoHoefel Разрывная линия?
Caird Coneheringaahing
@cairdcoinheringaahing Символы новой строки, предположительно.
Линн
0

Сетчатка 0.8.2 , 46 байт

.+
$*
{*M`1
^(..)+$
$&$&$&$&$&$&111
1(.*)\1
$1

Попробуйте онлайн! Объяснение:

.+
$*

Преобразовать в одинарный.

{

Повторяйте, пока значение не перестанет меняться.

*M`1

Выведите значение в десятичном виде.

^(..)+$
$&$&$&$&$&$&111

Если оно четное, умножьте на 6 и добавьте 3.

1(.*)\1
$1

Вычтите 1 и разделите на 2.

Конечный символ новой строки можно подавить, добавив ;перед символом {.

Нил
источник
0

C # (.NET Core) , 62 байта

a=>{for(;a>0;a=a%2<1?a*3+1:a/2)Console.Write(a+" ");return a;}

Попробуйте онлайн!

Ungolfed:

a => {
    for(; a > 0;                // until a equals 0
        a = a % 2 < 1 ?             // set a depending on if a is odd or even
                a * 3 + 1 :             // even
                a / 2                   // odd (minus one unnecessary because of int casting)
    )
        Console.Write(a + " "); // writes the current a to the console
    return a;                   // writes a to the console (always 0)
}
Meerkat
источник