OCaml实现代码挑战
OCaml implementation of code challenge
我正在做一个允许使用任何语言的每日代码挑战。我最近一直在研究 Real-World OCaml。我真的很想知道如何在惯用的 OCaml 中解决这个特殊的挑战。下面是我的两个 JavaScript 实现。挑战在于识别数学金字塔中的模式:
1
11
21
1211
111221
(格式为1个1,2个1,1个2,1个1,3个1,2个2,1个1,从下一个"level"或一行读出的数字)
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);
我仔细考虑过如何在 OCaml 中解决这个问题,但我确信我只是重新发明了一种基于 C 的方法。我考虑过递归遍历字符串并匹配头部和尾部......看看它们是否相等并将结果存储在某种元组或其他东西中......我有点难以将我的想法扭曲成正确的思考。
这是一个高级分解。
您想要迭代函数的东西。有循环+显示部分,还有迭代部分(如何从一层到下一层)。
每次迭代有两个步骤:
- 数连续数(把1211变成"one one, one two, two ones")
- 将计数列表转换为列表(将 "one one, one two, two ones" 转换为 111221)
现在,让我们考虑一下类型。我们从不将这些数字用作数字(没有加法等),因此它们可以被视为整数列表,或者在 OCaml 中 int list
.
另一方面,计数也是一个列表,但是列表的每个元素都是一对(计数,值)。例如 "one one, one two, two ones" 可以表示为 [(1, 1); (1, 2); (2, 1)]
。 OCaml 中此类事物的类型是 (int * int) list
.
换句话说,您的算法的重要部分将是:
int list -> (int * int) list
类型的函数,计算连续元素。
(int * int) list -> int list
类型的函数,将这些计数转换为新列表。
一旦你有了这些,你应该能够将这些碎片拼凑起来。玩得开心!
我正在做一个允许使用任何语言的每日代码挑战。我最近一直在研究 Real-World OCaml。我真的很想知道如何在惯用的 OCaml 中解决这个特殊的挑战。下面是我的两个 JavaScript 实现。挑战在于识别数学金字塔中的模式:
1 11 21 1211 111221
(格式为1个1,2个1,1个2,1个1,3个1,2个2,1个1,从下一个"level"或一行读出的数字)
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);
我仔细考虑过如何在 OCaml 中解决这个问题,但我确信我只是重新发明了一种基于 C 的方法。我考虑过递归遍历字符串并匹配头部和尾部......看看它们是否相等并将结果存储在某种元组或其他东西中......我有点难以将我的想法扭曲成正确的思考。
这是一个高级分解。
您想要迭代函数的东西。有循环+显示部分,还有迭代部分(如何从一层到下一层)。
每次迭代有两个步骤:
- 数连续数(把1211变成"one one, one two, two ones")
- 将计数列表转换为列表(将 "one one, one two, two ones" 转换为 111221)
现在,让我们考虑一下类型。我们从不将这些数字用作数字(没有加法等),因此它们可以被视为整数列表,或者在 OCaml 中 int list
.
另一方面,计数也是一个列表,但是列表的每个元素都是一对(计数,值)。例如 "one one, one two, two ones" 可以表示为 [(1, 1); (1, 2); (2, 1)]
。 OCaml 中此类事物的类型是 (int * int) list
.
换句话说,您的算法的重要部分将是:
int list -> (int * int) list
类型的函数,计算连续元素。(int * int) list -> int list
类型的函数,将这些计数转换为新列表。
一旦你有了这些,你应该能够将这些碎片拼凑起来。玩得开心!