Como puede saber, el factorial de un entero positivo n
es el producto de todos los enteros positivos que son iguales o menores n
.
Por ejemplo :
6! = 6*5*4*3*2*1 = 720
0! = 1
Ahora definiremos una operación especial con un nombre irrelevante como sumFac
:
Dado un entero positivo n
, sumFac(n)
es la suma de los factoriales de los dígitos.
Por ejemplo :
sumFac(132) = 1! + 3! + 2! = 9
Tarea
Su misión, ya sea que elija o no aceptarla, es devolver la secuencia (potencialmente infinita) de las aplicaciones sumFac
a un entero dado en la entrada.
Ejemplo: 132 -> 132, 9, 362880, 81369, 403927, ...
¡Pero eso no es todo! De hecho, las aplicaciones de sumFac
eventualmente crearán un ciclo. ¡También debes devolver este ciclo!
Si su idioma tiene un factorial incorporado, puede usarlo. No soy exigente con el tipo de retorno, solo tiene que devolver la secuencia de aplicaciones sumFac y el ciclo en un formato comprensible para un humano.
EDITAR: para ayudarlo a visualizar mejor cómo debería verse la salida, copié Leaky Nun's justo debajo:
[132, 9, 362880, 81369, 403927, 367953, 368772, 51128, 40444, 97, 367920, 368649, 404670, 5810, 40442, 75, 5160, 842, 40346, 775, 10200, 6, 720, 5043, 151, 122, 5, 120, 4, 24, 26, 722, 5044, 169, 363601, 1454]
¡Solo necesita detener la secuencia cuando el ciclo está por comenzar por segunda vez!
Pero este es el código de golf, por lo que gana la respuesta más corta en bytes.
Tabla de clasificación
Aquí hay un fragmento de pila para generar una tabla de clasificación regular y una descripción general de los ganadores por idioma.
/* Configuration */
var QUESTION_ID = 117583; // Obtain this from the url
// It will be like https://XYZ.stackexchange.com/questions/QUESTION_ID/... on any question page
var ANSWER_FILTER = "!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe";
var COMMENT_FILTER = "!)Q2B_A2kjfAiU78X(md6BoYk";
var OVERRIDE_USER = 68509; // This should be the user ID of the challenge author.
/* App */
var answers = [], answers_hash, answer_ids, answer_page = 1, more_answers = true, comment_page;
function answersUrl(index) {
return "https://api.stackexchange.com/2.2/questions/" + QUESTION_ID + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER;
}
function commentUrl(index, answers) {
return "https://api.stackexchange.com/2.2/answers/" + answers.join(';') + "/comments?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + COMMENT_FILTER;
}
function getAnswers() {
jQuery.ajax({
url: answersUrl(answer_page++),
method: "get",
dataType: "jsonp",
crossDomain: true,
success: function (data) {
answers.push.apply(answers, data.items);
answers_hash = [];
answer_ids = [];
data.items.forEach(function(a) {
a.comments = [];
var id = +a.share_link.match(/\d+/);
answer_ids.push(id);
answers_hash[id] = a;
});
if (!data.has_more) more_answers = false;
comment_page = 1;
getComments();
}
});
}
function getComments() {
jQuery.ajax({
url: commentUrl(comment_page++, answer_ids),
method: "get",
dataType: "jsonp",
crossDomain: true,
success: function (data) {
data.items.forEach(function(c) {
if (c.owner.user_id === OVERRIDE_USER)
answers_hash[c.post_id].comments.push(c);
});
if (data.has_more) getComments();
else if (more_answers) getAnswers();
else process();
}
});
}
getAnswers();
var SCORE_REG = /<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/;
var OVERRIDE_REG = /^Override\s*header:\s*/i;
function getAuthorName(a) {
return a.owner.display_name;
}
function process() {
var valid = [];
answers.forEach(function(a) {
var body = a.body;
a.comments.forEach(function(c) {
if(OVERRIDE_REG.test(c.body))
body = '<h1>' + c.body.replace(OVERRIDE_REG, '') + '</h1>';
});
var match = body.match(SCORE_REG);
if (match)
valid.push({
user: getAuthorName(a),
size: +match[2],
language: match[1],
link: a.share_link,
});
});
valid.sort(function (a, b) {
var aB = a.size,
bB = b.size;
return aB - bB
});
var languages = {};
var place = 1;
var lastSize = null;
var lastPlace = 1;
valid.forEach(function (a) {
if (a.size != lastSize)
lastPlace = place;
lastSize = a.size;
++place;
var answer = jQuery("#answer-template").html();
answer = answer.replace("{{PLACE}}", lastPlace + ".")
.replace("{{NAME}}", a.user)
.replace("{{LANGUAGE}}", a.language)
.replace("{{SIZE}}", a.size)
.replace("{{LINK}}", a.link);
answer = jQuery(answer);
jQuery("#answers").append(answer);
var lang = a.language;
if (/<a/.test(lang)) lang = jQuery(lang).text();
languages[lang] = languages[lang] || {lang: a.language, user: a.user, size: a.size, link: a.link};
});
var langs = [];
for (var lang in languages)
if (languages.hasOwnProperty(lang))
langs.push(languages[lang]);
langs.sort(function (a, b) {
if (a.lang > b.lang) return 1;
if (a.lang < b.lang) return -1;
return 0;
});
for (var i = 0; i < langs.length; ++i)
{
var language = jQuery("#language-template").html();
var lang = langs[i];
language = language.replace("{{LANGUAGE}}", lang.lang)
.replace("{{NAME}}", lang.user)
.replace("{{SIZE}}", lang.size)
.replace("{{LINK}}", lang.link);
language = jQuery(language);
jQuery("#languages").append(language);
}
}
body { text-align: left !important}
#answer-list {
padding: 10px;
width: 290px;
float: left;
}
#language-list {
padding: 10px;
width: 290px;
float: left;
}
table thead {
font-weight: bold;
}
table td {
padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b">
<div id="answer-list">
<h2>Leaderboard</h2>
<table class="answer-list">
<thead>
<tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr>
</thead>
<tbody id="answers">
</tbody>
</table>
</div>
<div id="language-list">
<h2>Winners by Language</h2>
<table class="language-list">
<thead>
<tr><td>Language</td><td>User</td><td>Score</td></tr>
</thead>
<tbody id="languages">
</tbody>
</table>
</div>
<table style="display: none">
<tbody id="answer-template">
<tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr>
</tbody>
</table>
<table style="display: none">
<tbody id="language-template">
<tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr>
</tbody>
</table>
Respuestas:
Jelly, 6 bytes
Try it online!
I don't see any other way to make it shorter other than to do as told.
Specs
132
(as command-line argument)[132, 9, 362880, 81369, 403927, 367953, 368772, 51128, 40444, 97, 367920, 368649, 404670, 5810, 40442, 75, 5160, 842, 40346, 775, 10200, 6, 720, 5043, 151, 122, 5, 120, 4, 24, 26, 722, 5044, 169, 363601, 1454]
fuente
Python 2, 88 bytes
Try it online!
fuente
05AB1E, 12 bytes
Try it online!
Explanation
fuente
s
, was wrong, nice answer.Brachylog, 17 bytes
Try it online!
Explanation
fuente
I
mean?ᵃ⁾
.ᵃ³
means "accumulate 3 times".ᵃ⁾
means "accumulate as many times as the last element of the input", which in that case isI
. SinceI
is a completely free variable, it will try values for it from0
to+inf
.Wolfram Language,
626056 bytesIt is really too bad that Wolfram Language has such abominably long function names. *Sigh*
Explanation:
fuente
Tr
.NestWhileList[...,All]
!JavaScript (ES6),
9189 bytesSaved 2 bytes thanks to fəˈnɛtɪk
It turns out to be quite similar to the other JS answer.
Show code snippet
fuente
ClojureScript,
146109 bytesYikes, that is a monstrosity. Someone please help me golf this...
Thanks
@cliffroot
for shaving off a whopping 37 bytes!This is an anonymous function, to run the function, you have to do this:
TIO doesn't have ClojureScript, so here's a link to a ClojureScript REPL.
Here's a link to a Clojure program which prints the last element in the list from 0 to 1000.
Here's the output for
9999
:I have a strong suspicion that all numbers must eventually settle at
1
or the loop[169 363601 1454]
.Ungolfed code:
Explanation coming soon!
fuente
for
can be(for[a s](apply *(range 1(-(int a)47))))
, can't it?let
#(loop[n[%]](let[f(apply +(for[a(str(last n))](apply *(range 1(-(int a)47)))))](if(some #{f}n)n(recur(conj n f)))))
(- ... 47)
in ClojureScript, justint
will suffice(inc(int a))
should do for ClojureScript and(-(int a)47)
for Clojure.Perl 6, 64 bytes
Try it
Expanded:
Every line above that has
{
starts a new bare block lambda with an implicit parameter of$_
.I used
[*] 2..$_
instead of[*] 1..$_
purely as a micro optimization.fuente
JavaScript, 92 bytes
Thanks @Shaggy for golfing off one byte with includes
Thanks @Neil for golfing off two bytes
Code separated into individual functions 92 bytes
Code on one line 92 bytes
Explanation
Initially call the function with just a single argument, therefore a=[].
If x exists in the array a return a
a.includes(x)?a:...
Otherwise, append x to a and pass the factorial digit sum and a to the function
(a.push(x),f(k(x),a))
Factorial Digit sum performed so that it will not exceed the maximum recursion limit.
List of all possible endpoints: 1, 2, 145, 169, 871, 872, 1454, 40585, 45361, 45362, 363601
Try it online!
fuente
f=(x,a=[])=>a.includes(x)?a:(a.push(x),f(k(x),a))
f(k(x),a,a.push(x))
? Also, I think you can writek=n=>n&&
to save another byte.Haskell,
8067 bytesTry it online! Usage:
([]#) 132
Edit: Saved 13 bytes with typs from Ørjan Johansen!
fuente
n
instead ofs
(same as in ovs's Python answer), thenf=([]#)
. (2) Switch the branches, inlines
, and useelem
.++
for:
also.n:
and changing=g
to=[]
, but it seems to be only a tie.Pyth, 9 bytes
Try it online!
This answer uses
.u
("Cumulative fixed-point. Apply until a result that has occurred before is found. Return all intermediate results.")fuente
Pyth, 30 bytes
Try It Here
fuente
Python 3, 110 bytes
Try it online!
fuente
R, 120 Bytes
fuente
o=scan()
, useel()
instead of[[1]]
, andgamma(n+1)=factorial(n)
which I believe saves a byte, and I thinkas.numeric
is the same asas.double
for integers, which also saves a byte, and you can usetoString
instead ofas.character
.Java 9 JSHell, 213 bytes
Try it online!
Note: This solution relies on the string representation of a number having code points in the range 48-57. Works for ASCII, UTF-8, Latin-1, all ISO-8859-* character sets, most code pages. Does not work for EBCDIC. I don't think anyone will deduct points for that. :)
Ungolfed:
Notes:
fuente
Pyth,
2211 bytesTry it online!
Lots of credit to Leaky Nun's answer, which introduced me to
.u
, and helped save a massive 11 bytes of this program.Explanation:
fuente
.u
. I guess I'll need to take a look through the character reference again to see if there are any other useful functions there.`N
to convert to string instead of+Nk
.N
would be obsolete then, and there comes a 9-byte solution...Axiom, 231 bytes
not golfed functions and some test
fuente
Java 7, 220 bytes
Explanation:
Test code:
Try it here.
Output:
fuente
GolfScript, 44 bytes
Try it online!
The factorial part is from here.
fuente
C, 161 bytes
See it work online.
fuente
TI-BASIC,
85796460 bytesSince this is running on a graphing calculator, there is limited RAM. Try testing it with numbers that loop quickly, like
169
.More Explanation:
If prod(L₁-X
works by subtracting the new element from the old list, then multiplying all the elements of the list together. If the element was already in the list, the product will be0
, a falsey value. Otherwise, the product will be a positive integer, a truthy value.fuente
Husk, 6 bytes
Try it online!
fuente
J,
4031 bytesEdit: 9 bytes saved using the improvements by FrownyFrog. Thanks!
Original code:
In this case I decided to count the bytes for the verb definition, since otherwise it doesn't work in the interpreter.
Explanation:
Try it online!
fuente
([:-.e.~)
->(1-e.~)
[:+/!@"."0@":@{:
is the same length, so there's no improvement with10#.inv
. Just had to drop the()
.Tcl, 143 bytes
Try it online!
fuente