代码挑战的OCaml实现
我正在做一个每日代码挑战,允许使用任何语言。我最近一直在使用真实世界的OCaml。我真的很想知道如何用惯用的OCaml解决这个特殊的挑战。下面是我的两个JavaScript实现。挑战在于识别数学金字塔中的模式: 一, 11 21 1211 111221 (模式为一个1、两个1、一个2、一个1、三个1、两个2、一个1,从下一个“级别”或行读取的数字)代码挑战的OCaml实现,ocaml,ocaml-core,Ocaml,Ocaml Core,我正在做一个每日代码挑战,允许使用任何语言。我最近一直在使用真实世界的OCaml。我真的很想知道如何用惯用的OCaml解决这个特殊的挑战。下面是我的两个JavaScript实现。挑战在于识别数学金字塔中的模式: 一, 11 21 1211 111221 (模式为一个1、两个1、一个2、一个1、三个1、两个2、一个1,从下一个“级别”或行读取的数字) 函数createNextLevel(上一级,当前级=0,最终级=40){ 让sub=''; 设level=''; //在字符串上迭代 for(设i=
函数createNextLevel(上一级,当前级=0,最终级=40){
让sub='';
设level='';
//在字符串上迭代
for(设i=0;i{
级别+=`${String(group.length)}${group[0]}`;
});
控制台日志(级别);
如果(当前级别<最终级别){
createNextLevelPlus(级别,当前级别+1)
}
}
var firstLevel='1';
createNextLevelPlus(第一级);
我曾经思考过如何在OCaml中解决这个问题,但我确信我只是在重新发明一种基于C的方法。我考虑过递归地遍历字符串并在头和尾上匹配。。。看看它们是否相等,并将结果存储在某种元组或其他东西中。。。我很难将我的思想扭曲到正确的思维中。这里有一个高级分解 您需要迭代函数的东西。有一个循环+显示部分和一个迭代部分(如何从一个级别转到下一个级别) 每个迭代中有两个步骤:
- 数一数连续的数字(将1211变为“一、一、二、二个一”)
- 将计数列表转换为列表(将“一、一、二、二个一”转换为111221)
int list
中
另一方面,计数也是一个列表,但列表中的每个元素都是一对(计数,值)。例如,“一个一个二个一”可以表示为[(1,1);(1,2);(2,1)]
。OCaml中此类内容的类型是(int*int)list
换句话说,算法的重要部分是:
- 一种类型为
的函数,用于对连续元素进行计数int list->(int*int)list
- 类型为
的函数,用于将这些计数转换为新列表(int*int)list->int list
一旦你有了这些,你应该能够把这些碎片放在一起。玩得开心 这是一个高级分解 您需要迭代函数的东西。有一个循环+显示部分和一个迭代部分(如何从一个级别转到下一个级别) 每个迭代中有两个步骤:
- 数一数连续的数字(将1211变为“一、一、二、二个一”)
- 将计数列表转换为列表(将“一、一、二、二个一”转换为111221)
int list
中
另一方面,计数也是一个列表,但列表中的每个元素都是一对(计数,值)。例如,“一个一个二个一”可以表示为[(1,1);(1,2);(2,1)]
。OCaml中此类内容的类型是(int*int)list
换句话说,算法的重要部分是:
- 一种类型为
的函数,用于对连续元素进行计数int list->(int*int)list
- 类型为
的函数,用于将这些计数转换为新列表(int*int)list->int list
一旦你有了这些,你应该能够把这些碎片放在一起。玩得开心 哇,谢谢你!这正是我要找的东西。很高兴能帮上忙!如果您希望在编写代码后对其进行一些审阅,如果您需要一些输入,请随时发布。哇,谢谢!这正是我要找的东西。很高兴能帮上忙!如果您希望在编写代码后对其进行一些检查,如果您需要一些输入,请随时发布。
function createNextLevel(previousLevel, currentLevel = 0, finalLevel = 40) {
let sub = '';
let level = '';
// iterate on string
for (let i = 0; i < previousLevel.length; i++) {
// if we don't have an element to the left or it's equal to current element
if (!previousLevel[i - 1] || previousLevel[i] === previousLevel[i - 1]) {
sub += previousLevel[i]; // sub '2'
} else {
level += String(sub.length) + sub[0]; // ''
sub = previousLevel[i];
}
// if we're at the end
if (i === previousLevel.length - 1) {
level += String(sub.length) + sub[0]; // '21'
}
}
console.log(level);
if (currentLevel < finalLevel) {
createNextLevel(level, currentLevel + 1)
}
}
var firstLevel = '1';
createNextLevel(firstLevel);
// A bit simpler approach
function createNextLevelPlus(str, currentLevel = 0, finalLevel = 10) {
var delimitedStr = '';
var level = '';
for (let i = 0; i < str.length; i++) {
if (!str[i + 1] || str[i] === str[i+1]) {
delimitedStr += str[i];
} else {
delimitedStr += str[i] + '|';
}
}
delimitedStr.split('|').forEach((group, idx, arr) => {
level += `${String(group.length)}${group[0]}`;
});
console.log(level);
if (currentLevel < finalLevel) {
createNextLevelPlus(level, currentLevel+1)
}
}
var firstLevel = '1';
createNextLevelPlus(firstLevel);