Support
Quality
Security
License
Reuse
Coming Soon for all Libraries!
Currently covering the most popular Java, JavaScript and Python libraries. See a SAMPLE HERE.
kandi's functional review helps you automatically verify the functionalities of the libraries and avoid rework.
ServerMap - Understand the topology of any distributed systems by visualizing how their components are interconnected. Clicking on a node reveals details about the component, such as its current status, and transaction count.
Realtime Active Thread Chart - Monitor active threads inside applications in real-time.
Request/Response Scatter Chart - Visualize request count and response patterns over time to identify potential problems. Transactions can be selected for additional detail by dragging over the chart.
CallStack - Gain code-level visibility to every transaction in a distributed environment, identifying bottlenecks and points of failure in a single view.
Inspector - View additional details on the application such as CPU usage, Memory/Garbage Collection, TPS, and JVM arguments.
License
Copyright 2018 NAVER Corp.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Segmented far pointer allocation in 16bit x86 MS-DOS real mode
int main(void)
{
char far *video_buffer = (char far *)0xA0000000L;
Set_Video_Mode(0x13);
while (!kbhit()) { };
Set_Video_Mode(0x03);
return 0;
}
Socket.IO - socket.on not being ran
socket.emit("statistics", {test: "just a message"}, (response) => {
console.log(response); // <-- should output "success"
});
socket.on("statistics", (data, callback) => {
console.log(data.test); // <-- should output "just a message"
callback("success");//<-- this will return to the sender/emitter
});
socket.timeout(5000).emit("statistics", {test: "just a message"}, (err, response) => {
if (err)
// the event was not acknowledged by the receiver in the delay given
else
console.log(response); // <-- output is "success"
});
this.socketio.timeout(5000).emit(
`${uuid}-statistics`,
{
result: { statistics: { members: guild.memberCount } },
error: false,
},
(err: any, data: any) => {
if (err) {
this.logger.error(err);
}
if (data) {
console.log(data);//<-- this is where your callback resolves to
}
}
);
const cb = (res: { result: T; error: boolean }, ack: any) => {
//do whatever you want with res
if (res.error) {
console.log("Error:",res.result);
ack("Errorfrom server");
}
socket.off(`${data.id}-${event}`, cb);
console.log("Success:",res.result)
ack("Success from server");//<--this callback will send back to the emitter
};
-----------------------
socket.emit("statistics", {test: "just a message"}, (response) => {
console.log(response); // <-- should output "success"
});
socket.on("statistics", (data, callback) => {
console.log(data.test); // <-- should output "just a message"
callback("success");//<-- this will return to the sender/emitter
});
socket.timeout(5000).emit("statistics", {test: "just a message"}, (err, response) => {
if (err)
// the event was not acknowledged by the receiver in the delay given
else
console.log(response); // <-- output is "success"
});
this.socketio.timeout(5000).emit(
`${uuid}-statistics`,
{
result: { statistics: { members: guild.memberCount } },
error: false,
},
(err: any, data: any) => {
if (err) {
this.logger.error(err);
}
if (data) {
console.log(data);//<-- this is where your callback resolves to
}
}
);
const cb = (res: { result: T; error: boolean }, ack: any) => {
//do whatever you want with res
if (res.error) {
console.log("Error:",res.result);
ack("Errorfrom server");
}
socket.off(`${data.id}-${event}`, cb);
console.log("Success:",res.result)
ack("Success from server");//<--this callback will send back to the emitter
};
-----------------------
socket.emit("statistics", {test: "just a message"}, (response) => {
console.log(response); // <-- should output "success"
});
socket.on("statistics", (data, callback) => {
console.log(data.test); // <-- should output "just a message"
callback("success");//<-- this will return to the sender/emitter
});
socket.timeout(5000).emit("statistics", {test: "just a message"}, (err, response) => {
if (err)
// the event was not acknowledged by the receiver in the delay given
else
console.log(response); // <-- output is "success"
});
this.socketio.timeout(5000).emit(
`${uuid}-statistics`,
{
result: { statistics: { members: guild.memberCount } },
error: false,
},
(err: any, data: any) => {
if (err) {
this.logger.error(err);
}
if (data) {
console.log(data);//<-- this is where your callback resolves to
}
}
);
const cb = (res: { result: T; error: boolean }, ack: any) => {
//do whatever you want with res
if (res.error) {
console.log("Error:",res.result);
ack("Errorfrom server");
}
socket.off(`${data.id}-${event}`, cb);
console.log("Success:",res.result)
ack("Success from server");//<--this callback will send back to the emitter
};
-----------------------
socket.emit("statistics", {test: "just a message"}, (response) => {
console.log(response); // <-- should output "success"
});
socket.on("statistics", (data, callback) => {
console.log(data.test); // <-- should output "just a message"
callback("success");//<-- this will return to the sender/emitter
});
socket.timeout(5000).emit("statistics", {test: "just a message"}, (err, response) => {
if (err)
// the event was not acknowledged by the receiver in the delay given
else
console.log(response); // <-- output is "success"
});
this.socketio.timeout(5000).emit(
`${uuid}-statistics`,
{
result: { statistics: { members: guild.memberCount } },
error: false,
},
(err: any, data: any) => {
if (err) {
this.logger.error(err);
}
if (data) {
console.log(data);//<-- this is where your callback resolves to
}
}
);
const cb = (res: { result: T; error: boolean }, ack: any) => {
//do whatever you want with res
if (res.error) {
console.log("Error:",res.result);
ack("Errorfrom server");
}
socket.off(`${data.id}-${event}`, cb);
console.log("Success:",res.result)
ack("Success from server");//<--this callback will send back to the emitter
};
-----------------------
socket.emit("statistics", {test: "just a message"}, (response) => {
console.log(response); // <-- should output "success"
});
socket.on("statistics", (data, callback) => {
console.log(data.test); // <-- should output "just a message"
callback("success");//<-- this will return to the sender/emitter
});
socket.timeout(5000).emit("statistics", {test: "just a message"}, (err, response) => {
if (err)
// the event was not acknowledged by the receiver in the delay given
else
console.log(response); // <-- output is "success"
});
this.socketio.timeout(5000).emit(
`${uuid}-statistics`,
{
result: { statistics: { members: guild.memberCount } },
error: false,
},
(err: any, data: any) => {
if (err) {
this.logger.error(err);
}
if (data) {
console.log(data);//<-- this is where your callback resolves to
}
}
);
const cb = (res: { result: T; error: boolean }, ack: any) => {
//do whatever you want with res
if (res.error) {
console.log("Error:",res.result);
ack("Errorfrom server");
}
socket.off(`${data.id}-${event}`, cb);
console.log("Success:",res.result)
ack("Success from server");//<--this callback will send back to the emitter
};
Docker container ubuntu 21 root to root (local machine to container) gives permission issues on file saves
version: "3.0"
services:
something:
image: example-image
volumes:
- /user/path1:/container/path1
- /user/path2:/container/path2
# The double $ is needed to indicate that the variable is in the container
command: ["bash", "-c", "chown -R $$HOST_UID:$$HOST_GID /container/path1 /container/path2; useradd -g $$HOST_GID -u $$HOST_UID user; su -s /bin/bash user"]
environment:
HOST_GID: 100
HOST_UID: 1000
version: "3.0"
services:
something:
image: example-image
volumes:
- /user/path1:/container/path1
- /user/path2:/container/path2
command: ["bash"]
environment:
HOST_UID: 1000
HOST_GID: 100
# The double $ is needed to indicate that the variable is in the container
PROMPT_COMMAND: "chown $$HOST_UID:$$HOST_GID -R /container/path1 /container/path2"
-----------------------
version: "3.0"
services:
something:
image: example-image
volumes:
- /user/path1:/container/path1
- /user/path2:/container/path2
# The double $ is needed to indicate that the variable is in the container
command: ["bash", "-c", "chown -R $$HOST_UID:$$HOST_GID /container/path1 /container/path2; useradd -g $$HOST_GID -u $$HOST_UID user; su -s /bin/bash user"]
environment:
HOST_GID: 100
HOST_UID: 1000
version: "3.0"
services:
something:
image: example-image
volumes:
- /user/path1:/container/path1
- /user/path2:/container/path2
command: ["bash"]
environment:
HOST_UID: 1000
HOST_GID: 100
# The double $ is needed to indicate that the variable is in the container
PROMPT_COMMAND: "chown $$HOST_UID:$$HOST_GID -R /container/path1 /container/path2"
How to obtain the length of the last word in the string
public int lengthOfLastWord(String s) {
String [] arr = s.trim().split(" ");
return arr[arr.length-1].length();
}
-----------------------
for (int i = s.length() - 1; i >= 0; i--) {
ch = s.charAt(i);
reversed += ch;
}
public class HW5 {
public static void main(String[] args) {
String s = "My name is Mathew";
int count = lengthOfLastWord(s);
System.out.println(count);
}
public static int lengthOfLastWord(String s) {
int count = 0;
int countWhite = 0;
char ch;
String reversed = "";
System.out.println("original string is----" + s);
for (int i = s.length() - 1; i >= 0; i--) {
ch = s.charAt(i);
reversed += ch;
}
System.out.println("reversed string is----" + reversed);
for (int i = 0; i < reversed.length(); i++) {
if (!Character.isWhitespace(reversed.charAt(i)))
count++;
if (count > 1 && Character.isWhitespace(reversed.charAt(i)) == true) {
break;
}
}
return count;
}
}
and the output is :
original string is----My name is Mathew
reversed string is----wehtaM si eman yM
6
-----------------------
for (int i = s.length() - 1; i >= 0; i--) {
ch = s.charAt(i);
reversed += ch;
}
public class HW5 {
public static void main(String[] args) {
String s = "My name is Mathew";
int count = lengthOfLastWord(s);
System.out.println(count);
}
public static int lengthOfLastWord(String s) {
int count = 0;
int countWhite = 0;
char ch;
String reversed = "";
System.out.println("original string is----" + s);
for (int i = s.length() - 1; i >= 0; i--) {
ch = s.charAt(i);
reversed += ch;
}
System.out.println("reversed string is----" + reversed);
for (int i = 0; i < reversed.length(); i++) {
if (!Character.isWhitespace(reversed.charAt(i)))
count++;
if (count > 1 && Character.isWhitespace(reversed.charAt(i)) == true) {
break;
}
}
return count;
}
}
and the output is :
original string is----My name is Mathew
reversed string is----wehtaM si eman yM
6
-----------------------
for (int i = s.length() - 1; i >= 0; i--) {
ch = s.charAt(i);
reversed += ch;
}
public class HW5 {
public static void main(String[] args) {
String s = "My name is Mathew";
int count = lengthOfLastWord(s);
System.out.println(count);
}
public static int lengthOfLastWord(String s) {
int count = 0;
int countWhite = 0;
char ch;
String reversed = "";
System.out.println("original string is----" + s);
for (int i = s.length() - 1; i >= 0; i--) {
ch = s.charAt(i);
reversed += ch;
}
System.out.println("reversed string is----" + reversed);
for (int i = 0; i < reversed.length(); i++) {
if (!Character.isWhitespace(reversed.charAt(i)))
count++;
if (count > 1 && Character.isWhitespace(reversed.charAt(i)) == true) {
break;
}
}
return count;
}
}
and the output is :
original string is----My name is Mathew
reversed string is----wehtaM si eman yM
6
-----------------------
public int lengthOfLastWord(String string) {
int whiteSpaceIndex = string.lastIndexOf(" ");
if (whiteSpaceIndex == -1) {
return string.length();
}
int lastIndex = string.length() - 1;
return lastIndex - whiteSpaceIndex;
}
-----------------------
public static int getLastWordLength(String source) {
return (int) IntStream.iterate(source.length() - 1, i -> i >= 0, i -> --i)
.map(source::charAt)
.dropWhile(ch -> !Character.isLetter(ch))
.takeWhile(Character::isLetter)
.count();
}
new StringBuilder(source).reverse().toString();
public static int getLastWordLength(String source) {
int end = -1; // initialized with illegal index
int start = 0;
for (int i = source.length() - 1; i >= 0; i--) {
if (Character.isLetter(source.charAt(i)) && end == -1) {
end = i;
}
if (Character.isWhitespace(source.charAt(i)) && end != -1) {
start = i;
break;
}
}
return end == -1 ? 0 : end - start;
}
public static void main(String[] args) {
System.out.println(getLastWord("Humpty Dumpty sat on a wall % _ (&)"));
}
4 - last word is "wall"
-----------------------
public static int getLastWordLength(String source) {
return (int) IntStream.iterate(source.length() - 1, i -> i >= 0, i -> --i)
.map(source::charAt)
.dropWhile(ch -> !Character.isLetter(ch))
.takeWhile(Character::isLetter)
.count();
}
new StringBuilder(source).reverse().toString();
public static int getLastWordLength(String source) {
int end = -1; // initialized with illegal index
int start = 0;
for (int i = source.length() - 1; i >= 0; i--) {
if (Character.isLetter(source.charAt(i)) && end == -1) {
end = i;
}
if (Character.isWhitespace(source.charAt(i)) && end != -1) {
start = i;
break;
}
}
return end == -1 ? 0 : end - start;
}
public static void main(String[] args) {
System.out.println(getLastWord("Humpty Dumpty sat on a wall % _ (&)"));
}
4 - last word is "wall"
-----------------------
public static int getLastWordLength(String source) {
return (int) IntStream.iterate(source.length() - 1, i -> i >= 0, i -> --i)
.map(source::charAt)
.dropWhile(ch -> !Character.isLetter(ch))
.takeWhile(Character::isLetter)
.count();
}
new StringBuilder(source).reverse().toString();
public static int getLastWordLength(String source) {
int end = -1; // initialized with illegal index
int start = 0;
for (int i = source.length() - 1; i >= 0; i--) {
if (Character.isLetter(source.charAt(i)) && end == -1) {
end = i;
}
if (Character.isWhitespace(source.charAt(i)) && end != -1) {
start = i;
break;
}
}
return end == -1 ? 0 : end - start;
}
public static void main(String[] args) {
System.out.println(getLastWord("Humpty Dumpty sat on a wall % _ (&)"));
}
4 - last word is "wall"
-----------------------
public static int getLastWordLength(String source) {
return (int) IntStream.iterate(source.length() - 1, i -> i >= 0, i -> --i)
.map(source::charAt)
.dropWhile(ch -> !Character.isLetter(ch))
.takeWhile(Character::isLetter)
.count();
}
new StringBuilder(source).reverse().toString();
public static int getLastWordLength(String source) {
int end = -1; // initialized with illegal index
int start = 0;
for (int i = source.length() - 1; i >= 0; i--) {
if (Character.isLetter(source.charAt(i)) && end == -1) {
end = i;
}
if (Character.isWhitespace(source.charAt(i)) && end != -1) {
start = i;
break;
}
}
return end == -1 ? 0 : end - start;
}
public static void main(String[] args) {
System.out.println(getLastWord("Humpty Dumpty sat on a wall % _ (&)"));
}
4 - last word is "wall"
-----------------------
public static int getLastWordLength(String source) {
return (int) IntStream.iterate(source.length() - 1, i -> i >= 0, i -> --i)
.map(source::charAt)
.dropWhile(ch -> !Character.isLetter(ch))
.takeWhile(Character::isLetter)
.count();
}
new StringBuilder(source).reverse().toString();
public static int getLastWordLength(String source) {
int end = -1; // initialized with illegal index
int start = 0;
for (int i = source.length() - 1; i >= 0; i--) {
if (Character.isLetter(source.charAt(i)) && end == -1) {
end = i;
}
if (Character.isWhitespace(source.charAt(i)) && end != -1) {
start = i;
break;
}
}
return end == -1 ? 0 : end - start;
}
public static void main(String[] args) {
System.out.println(getLastWord("Humpty Dumpty sat on a wall % _ (&)"));
}
4 - last word is "wall"
Amplify Invalid feature flag configuration on build
$ amplify --version
Using JS to show HTML output of calculation
document.getElementById("submitBtn").addEventListener("click",function(){
let gen = document.querySelector('#gender').value
let weight = document.querySelector('#weight').value
let height = document.querySelector('#height').value
let ages = document.querySelector('#age').value
calcBMR(gen,weight,height,ages)
})
function calcBMR(gender, weightKG, heightCM, age) {
let BMR
// Calculate BMR
if (gender = 'male') {
BMR = 10 * weightKG + 6.25 * heightCM - 5 * age + 5;
} else {
BMR = 10 * weightKG + 6.25 * heightCM - 5 * age - 161;
}
document.querySelector('#output').textContent = BMR;
}
<body>
<script src="./script.js"></script>
<section>
<form id="bmrForm">
<input type="text" id="gender" placeholder="Male or female?">
<input type="number" id="weight" placeholder="Weight in KG">
<input type="number" id="height" placeholder="Height in CM">
<input type="number" id="age" placeholder="How old are you?">
<button id="submitBtn">Do Magic!</button>
</form>
<p id="output">0</p>
</section>
</body>
-----------------------
document.getElementById("submitBtn").addEventListener("click",function(){
let gen = document.querySelector('#gender').value
let weight = document.querySelector('#weight').value
let height = document.querySelector('#height').value
let ages = document.querySelector('#age').value
calcBMR(gen,weight,height,ages)
})
function calcBMR(gender, weightKG, heightCM, age) {
let BMR
// Calculate BMR
if (gender = 'male') {
BMR = 10 * weightKG + 6.25 * heightCM - 5 * age + 5;
} else {
BMR = 10 * weightKG + 6.25 * heightCM - 5 * age - 161;
}
document.querySelector('#output').textContent = BMR;
}
<body>
<script src="./script.js"></script>
<section>
<form id="bmrForm">
<input type="text" id="gender" placeholder="Male or female?">
<input type="number" id="weight" placeholder="Weight in KG">
<input type="number" id="height" placeholder="Height in CM">
<input type="number" id="age" placeholder="How old are you?">
<button id="submitBtn">Do Magic!</button>
</form>
<p id="output">0</p>
</section>
</body>
-----------------------
let out = document.getElementById("output");
let gender = document.getElementById("gender");
let height = document.getElementById("height");
let weight = document.getElementById("weight");
let age = document.getElementById("age");
// If you want to pass arguments to the event handler, you need to wrap the handler call in another function
document.getElementById("submitBtn").addEventListener("click", function(){calcBMR(gender.value.toLowerCase(), +weight.value, +height.value, +age.value)});
function calcBMR(gender, weightKG, heightCM, age) {
let BMR = null; // Declare the variable in the function scope
console.log(gender, weightKG, heightCM, age);
// Calculate BMR
if (gender === 'male') {
BMR = 10 * weightKG + 6.25 * heightCM - 5 * age + 5;
} else {
BMR = 10 * weightKG + 6.25 * heightCM - 5 * age - 161;
}
console.log(BMR);
output.textContent = BMR;
}
<body>
<script src="./script.js"></script>
<section>
<form id="bmrForm" onsubmit="calcBMR()">
<input type="text" id="gender" placeholder="Male or female?">
<input type="number" id="weight" placeholder="Weight in KG">
<input type="number" id="height" placeholder="Height in CM">
<input type="number" id="age" placeholder="How old are you?">
<button type="button" id="submitBtn">Do Magic!</button>
</form>
<p id="output">0</p>
</section>
</body>
-----------------------
let out = document.getElementById("output");
let gender = document.getElementById("gender");
let height = document.getElementById("height");
let weight = document.getElementById("weight");
let age = document.getElementById("age");
// If you want to pass arguments to the event handler, you need to wrap the handler call in another function
document.getElementById("submitBtn").addEventListener("click", function(){calcBMR(gender.value.toLowerCase(), +weight.value, +height.value, +age.value)});
function calcBMR(gender, weightKG, heightCM, age) {
let BMR = null; // Declare the variable in the function scope
console.log(gender, weightKG, heightCM, age);
// Calculate BMR
if (gender === 'male') {
BMR = 10 * weightKG + 6.25 * heightCM - 5 * age + 5;
} else {
BMR = 10 * weightKG + 6.25 * heightCM - 5 * age - 161;
}
console.log(BMR);
output.textContent = BMR;
}
<body>
<script src="./script.js"></script>
<section>
<form id="bmrForm" onsubmit="calcBMR()">
<input type="text" id="gender" placeholder="Male or female?">
<input type="number" id="weight" placeholder="Weight in KG">
<input type="number" id="height" placeholder="Height in CM">
<input type="number" id="age" placeholder="How old are you?">
<button type="button" id="submitBtn">Do Magic!</button>
</form>
<p id="output">0</p>
</section>
</body>
-----------------------
function calcBMR(e) {
e.preventDefault();
var elements = document.getElementById("bmrForm").elements; // logic to get all form elements
var obj ={};
for(var i = 0 ; i < elements.length ; i++){
var item = elements.item(i);
obj[item.id] = item.value;
}
const {gender, weight, height, age } = obj; //Get values from obj
// Calculate BMR
let BMR = '';
if (gender === 'male') {
BMR = 10 * weight + 6.25 * height - 5 * age + 5;
} else {
BMR = 10 * weight + 6.25 * height - 5 * age - 161;
}
console.log(BMR);
}
-----------------------
function calcBMR() {
let gender = document.getElementById("gender").value;
let weightKG = document.getElementById("weight").value;
let heightCM = document.getElementById("height").value;
let age = document.getElementById("age").value;
let BMR;
// Calculate BMR
if (gender === 'male') {
BMR = 10 * weightKG + 6.25 * heightCM - 5 * age + 5;
} else {
BMR = 10 * weightKG + 6.25 * heightCM - 5 * age - 161;
}
console.log(BMR);
document.getElementById("output").textContent = BMR;
return false;
}
<body>
<script src="./script.js"></script>
<section>
<form id="bmrForm" onsubmit="return calcBMR()">
<input type="text" id="gender" placeholder="Male or female?">
<input type="number" id="weight" placeholder="Weight in KG">
<input type="number" id="height" placeholder="Height in CM">
<input type="number" id="age" placeholder="How old are you?">
<button type="submit" id="submitBtn">Do Magic!</button>
</form>
<p id="output">0</p>
</section>
-----------------------
function calcBMR() {
let gender = document.getElementById("gender").value;
let weightKG = document.getElementById("weight").value;
let heightCM = document.getElementById("height").value;
let age = document.getElementById("age").value;
let BMR;
// Calculate BMR
if (gender === 'male') {
BMR = 10 * weightKG + 6.25 * heightCM - 5 * age + 5;
} else {
BMR = 10 * weightKG + 6.25 * heightCM - 5 * age - 161;
}
console.log(BMR);
document.getElementById("output").textContent = BMR;
return false;
}
<body>
<script src="./script.js"></script>
<section>
<form id="bmrForm" onsubmit="return calcBMR()">
<input type="text" id="gender" placeholder="Male or female?">
<input type="number" id="weight" placeholder="Weight in KG">
<input type="number" id="height" placeholder="Height in CM">
<input type="number" id="age" placeholder="How old are you?">
<button type="submit" id="submitBtn">Do Magic!</button>
</form>
<p id="output">0</p>
</section>
-----------------------
document.getElementById("bmrForm").addEventListener("submit", calcBMR);
const output = document.getElementById('output');
function calcBMR(event) {
// Get the [gender, weightKG, heightCM, age] value
let gender = document.getElementById('gender').value;
let weightKG = document.getElementById('weight').value;
let heightCM = document.getElementById('height').value;
let age = document.getElementById('age').value;
// Set default BMR to 0
let BMR = 0;
// Calculate BMR
if (gender = 'male') {
BMR = 10 * weightKG + 6.25 * heightCM - 5 * age + 5;
} else {
BMR = 10 * weightKG + 6.25 * heightCM - 5 * age - 161;
}
console.log(BMR);
output.innerText = BMR;
// Cancel form submit
event.preventDefault();
return;
}
<body>
<script src="./script.js"></script>
<section>
<form id="bmrForm">
<input type="text" id="gender" placeholder="Male or female?">
<input type="number" id="weight" placeholder="Weight in KG">
<input type="number" id="height" placeholder="Height in CM">
<input type="number" id="age" placeholder="How old are you?">
<button type="submit" id="submitBtn">Do Magic!</button>
</form>
<p id="output">0</p>
</section>
</body>
-----------------------
document.getElementById("bmrForm").addEventListener("submit", calcBMR);
const output = document.getElementById('output');
function calcBMR(event) {
// Get the [gender, weightKG, heightCM, age] value
let gender = document.getElementById('gender').value;
let weightKG = document.getElementById('weight').value;
let heightCM = document.getElementById('height').value;
let age = document.getElementById('age').value;
// Set default BMR to 0
let BMR = 0;
// Calculate BMR
if (gender = 'male') {
BMR = 10 * weightKG + 6.25 * heightCM - 5 * age + 5;
} else {
BMR = 10 * weightKG + 6.25 * heightCM - 5 * age - 161;
}
console.log(BMR);
output.innerText = BMR;
// Cancel form submit
event.preventDefault();
return;
}
<body>
<script src="./script.js"></script>
<section>
<form id="bmrForm">
<input type="text" id="gender" placeholder="Male or female?">
<input type="number" id="weight" placeholder="Weight in KG">
<input type="number" id="height" placeholder="Height in CM">
<input type="number" id="age" placeholder="How old are you?">
<button type="submit" id="submitBtn">Do Magic!</button>
</form>
<p id="output">0</p>
</section>
</body>
-----------------------
// your form
var form = document.getElementById("formId");
var DoMagic = function(event)
{
event.preventDefault();
var elements = form.elements;
if (elements["gender"].value == "male")
{
var result = 10 * elements["weight"].value + 6.25 * elements["height"].value - 5 * elements["age"].value + 5;
}
else
{
var result = 10 * elements["weight"].value + 6.25 * elements["height"].value - 5 * elements["age"].value - 161;
}
document.getElementById("result").textContent = "Result: " + result;
}
// attach event listener
form.addEventListener("submit", DoMagic, true);
<form id = "formId">
<label>Gender</label>
<select name="gender">
<option value="male">Male</option>
<option value="female">Female</option>
</select>
<br>
<label>Weight (kg)</label>
<input name="weight" type="number">
<br>
<label>Height (cm)</label>
<input name="height" type="number">
<br>
<label>Age (years)</label>
<input name="age" type="number">
<br>
<input type="submit" value="Do Magic!">
</form>
<span id='result'> </span>
-----------------------
// your form
var form = document.getElementById("formId");
var DoMagic = function(event)
{
event.preventDefault();
var elements = form.elements;
if (elements["gender"].value == "male")
{
var result = 10 * elements["weight"].value + 6.25 * elements["height"].value - 5 * elements["age"].value + 5;
}
else
{
var result = 10 * elements["weight"].value + 6.25 * elements["height"].value - 5 * elements["age"].value - 161;
}
document.getElementById("result").textContent = "Result: " + result;
}
// attach event listener
form.addEventListener("submit", DoMagic, true);
<form id = "formId">
<label>Gender</label>
<select name="gender">
<option value="male">Male</option>
<option value="female">Female</option>
</select>
<br>
<label>Weight (kg)</label>
<input name="weight" type="number">
<br>
<label>Height (cm)</label>
<input name="height" type="number">
<br>
<label>Age (years)</label>
<input name="age" type="number">
<br>
<input type="submit" value="Do Magic!">
</form>
<span id='result'> </span>
-----------------------
<body>
<section>
<form id="bmrForm">
<input type="text" id="gender" placeholder="Male or female?" name="gender">
<input type="number" id="weight" placeholder="Weight in KG" name="weight">
<input type="number" id="height" placeholder="Height in CM" name="height">
<input type="number" id="age" placeholder="How old are you?" name="age">
<button type="submit" id="submitBtn">Do Magic!</button>
</form>
<p id="output">0</p>
</section>
</body>
document.getElementById("bmrForm").addEventListener("submit", calcBMR);
const output = document.querySelector('#output')
function calcBMR(e) {
e.preventDefault();
output.innerText = ''
const formData = new FormData(e.target)
const { age, gender, height, weight} = Object.fromEntries(formData);
let BMR = 0
// Calculate BMR
if (gender === 'male') {
BMR = 10 * parseInt(weight) + 6.25 * parseInt(height) - 5 * parseInt(age) + 5;
} else {
BMR = 10 * parseInt(weight) + 6.25 * parseInt(height) - 5 * parseInt(age) - 161;
}
output.innerText = BMR
}
-----------------------
<body>
<section>
<form id="bmrForm">
<input type="text" id="gender" placeholder="Male or female?" name="gender">
<input type="number" id="weight" placeholder="Weight in KG" name="weight">
<input type="number" id="height" placeholder="Height in CM" name="height">
<input type="number" id="age" placeholder="How old are you?" name="age">
<button type="submit" id="submitBtn">Do Magic!</button>
</form>
<p id="output">0</p>
</section>
</body>
document.getElementById("bmrForm").addEventListener("submit", calcBMR);
const output = document.querySelector('#output')
function calcBMR(e) {
e.preventDefault();
output.innerText = ''
const formData = new FormData(e.target)
const { age, gender, height, weight} = Object.fromEntries(formData);
let BMR = 0
// Calculate BMR
if (gender === 'male') {
BMR = 10 * parseInt(weight) + 6.25 * parseInt(height) - 5 * parseInt(age) + 5;
} else {
BMR = 10 * parseInt(weight) + 6.25 * parseInt(height) - 5 * parseInt(age) - 161;
}
output.innerText = BMR
}
How to automatically show a zoomed in view of the location in ArcGIS Esri Map?
export function addPointToExtent(
pto: __esri.Point,
ext: __esri.geometry.Extent
): __esri.geometry.Extent {
if (!pto) {
return ext;
}
let e;
if (!ext) {
e = new Extent({
xmin: pto.x,
xmax: pto.x,
ymin: pto.y,
ymax: pto.y,
spatialReference: {
wkid: 102100
}
});
} else {
e = ext.clone();
if (pto.x < e.xmin) {
e.xmin = pto.x;
}
if (pto.x > e.xmax) {
ext.xmax = pto.x;
}
if (pto.y < e.ymin) {
e.ymin = pto.y;
}
if (pto.y > e.ymax) {
ext.ymax = pto.y;
}
}
return e;
}
let ext = addPointToExtent(geoms[0] as Point, null);
for (let i = 1; i < geoms.length; i++) {
ext = addPointToExtent(geoms[i], ext);
}
view.goTo({ target: ext.expand(1.1) })
-----------------------
export function addPointToExtent(
pto: __esri.Point,
ext: __esri.geometry.Extent
): __esri.geometry.Extent {
if (!pto) {
return ext;
}
let e;
if (!ext) {
e = new Extent({
xmin: pto.x,
xmax: pto.x,
ymin: pto.y,
ymax: pto.y,
spatialReference: {
wkid: 102100
}
});
} else {
e = ext.clone();
if (pto.x < e.xmin) {
e.xmin = pto.x;
}
if (pto.x > e.xmax) {
ext.xmax = pto.x;
}
if (pto.y < e.ymin) {
e.ymin = pto.y;
}
if (pto.y > e.ymax) {
ext.ymax = pto.y;
}
}
return e;
}
let ext = addPointToExtent(geoms[0] as Point, null);
for (let i = 1; i < geoms.length; i++) {
ext = addPointToExtent(geoms[i], ext);
}
view.goTo({ target: ext.expand(1.1) })
-----------------------
export function addPointToExtent(
pto: __esri.Point,
ext: __esri.geometry.Extent
): __esri.geometry.Extent {
if (!pto) {
return ext;
}
let e;
if (!ext) {
e = new Extent({
xmin: pto.x,
xmax: pto.x,
ymin: pto.y,
ymax: pto.y,
spatialReference: {
wkid: 102100
}
});
} else {
e = ext.clone();
if (pto.x < e.xmin) {
e.xmin = pto.x;
}
if (pto.x > e.xmax) {
ext.xmax = pto.x;
}
if (pto.y < e.ymin) {
e.ymin = pto.y;
}
if (pto.y > e.ymax) {
ext.ymax = pto.y;
}
}
return e;
}
let ext = addPointToExtent(geoms[0] as Point, null);
for (let i = 1; i < geoms.length; i++) {
ext = addPointToExtent(geoms[i], ext);
}
view.goTo({ target: ext.expand(1.1) })
-----------------------
view.whenLayerView(dataFeedLayer).then(() => {
view.goTo({ target: dataFeedLayer.fullExtent.expand(1.2) })
});
dataFeedLayer.queryExtent().then((results) => {
view.goTo({ target: results.extent.expand(1.2) })
});
-----------------------
view.whenLayerView(dataFeedLayer).then(() => {
view.goTo({ target: dataFeedLayer.fullExtent.expand(1.2) })
});
dataFeedLayer.queryExtent().then((results) => {
view.goTo({ target: results.extent.expand(1.2) })
});
Problems computing cdist of two columns in two different dataframes
import pandas as pd
import numpy as np
import scipy.spatial.distance as sp
# df_sample and DF are OP's dictionaries
df_sample_df = pd.DataFrame(df_sample)
DF_df = pd.DataFrame(DF)
Ax = df_sample_df['Fingerprint'] = df_sample_df['Fingerprint'].apply(lambda x: np.array(x))
Bx = DF_df['Geopos Ack'] = DF_df['Geopos Ack'].apply(lambda x: np.array(x))
A = Ax.to_numpy()
B = Bx.to_numpy()
AA = np.stack(A)
BB = np.stack(B)
d = sp.cdist(AA,BB, 'euclidean')
print(f'd.shape = {d.shape}')
print(f'd[0, 0] = {d[0, 0]}')
print(f'L2(AA[0],BB[0]) = {np.sum((AA[0] - BB[0])**2)**0.5}')
d.shape = (3, 10)
d[0, 0] = 34.57536840006191
L2(AA[0],BB[0]) = 34.57536840006192
-----------------------
import pandas as pd
import numpy as np
import scipy.spatial.distance as sp
# df_sample and DF are OP's dictionaries
df_sample_df = pd.DataFrame(df_sample)
DF_df = pd.DataFrame(DF)
Ax = df_sample_df['Fingerprint'] = df_sample_df['Fingerprint'].apply(lambda x: np.array(x))
Bx = DF_df['Geopos Ack'] = DF_df['Geopos Ack'].apply(lambda x: np.array(x))
A = Ax.to_numpy()
B = Bx.to_numpy()
AA = np.stack(A)
BB = np.stack(B)
d = sp.cdist(AA,BB, 'euclidean')
print(f'd.shape = {d.shape}')
print(f'd[0, 0] = {d[0, 0]}')
print(f'L2(AA[0],BB[0]) = {np.sum((AA[0] - BB[0])**2)**0.5}')
d.shape = (3, 10)
d[0, 0] = 34.57536840006191
L2(AA[0],BB[0]) = 34.57536840006192
Understanding Grossman & Zeitman's Algorithm
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2 3
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4
i=1 2 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4
i=1 2 3 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3 5
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6
i=1 2 3 4 5 6
i=2 3 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7
i=1 2 3 4 5 6 7
i=2 3 5 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8
i=1 2 3 4 5 6 7 8
i=2 3 5 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9
i=1 2 3 4 5 6 7 8 9
i=2 3 5 7 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
i=2 3 5 7 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11
i=1 2 3 4 5 6 7 8 9 10 11
i=2 3 5 7 9 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11 12
i=1 2 3 4 5 6 7 8 9 10 11 12
i=2 3 5 7 9 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11 12 13
i=1 2 3 4 5 6 7 8 9 10 11 12 13
i=2 3 5 7 9 11 13
i=3 5 13
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 2
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 3
i=1 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 4
i=1 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 5
i=1 5
i=2 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 6
i=1 6
i=2 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 7
i=1 7
i=2 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 8
i=1 8
i=2 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 9
i=1 9
i=2 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 10
i=1 10
i=2 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 11
i=1 11
i=2 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 12
i=1 12
i=2 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 13
i=1 13
i=2 13
i=3 13
/**
* File: Ackermann.java
* Author: Keith Schwarz (htiek@cs.stanford.edu)
*
* An implementation of a variation of Grossman and Zeitman's fast algorithm
* for computing the Ackermann function. This implementation uses O(i) space
* to compute A(i, n), and takes O(A(i, n)) time. The only operation required
* on integers is "increment an integer" and "copy an integer." While this is
* implemented using vanilla ints, it could easily be extended to use BigInteger
* types or the like.
*/
public class Ackermann {
public static int ackermann(int i, int n) {
/* Bounds-check. */
if (i < 0 || n < 0) throw new RuntimeException("Invalid arguments.");
/* Positions array stores what column we're in in each row of
* the table. Initially this is all -1 to signify that we're just
* before the first column.
*/
int[] positions = new int[i + 1];
for (int j = 0; j < positions.length; j++) {
positions[j] = -1;
}
/* Values array stores the value currently in the filled column
* in each row. The value in the zeroth row is set to zero because
* our algorithm works by repeatedly incrementing its value and
* we need it to be the case that A(0, 0) = 1. Since we start off
* with "A(0, -1)" computed, we place a zero there.
*
* All the other values are set to 1. This corresponds to the rule
* that A(i, 0) = A(i - 1, 1), meaning we're waiting for column 1
* to come up in the level below us.
*/
int[] values = new int[i + 1];
for (int j = 1; j < values.length; j++) {
values[j] = 1;
}
/* Run the algorithm until we compute A(i, n), which happens when
* positions[i] == n.
*/
while (positions[i] != n) {
/* Push the value in the bottom row forward and increment it to simulate
* computing the next value of A(0, *).
*/
values[0]++;
positions[0]++;
/* Now, do the ripple. We continue rippling upward while
*
* 1. There's a layer above us to ripple to, and
* 2. The value above us equals our current position.
*/
for (int j = 1; j <= i && positions[j - 1] == values[j]; j++) {
values[j] = values[j - 1]; // Copy the value
positions[j]++; // Shift forward a column
}
}
return values[i];
}
public static void main(String[] args) {
if (args.length != 2) {
System.err.println("Usage: java Ackermann i n");
return;
}
int i = Integer.parseInt(args[0]);
int n = Integer.parseInt(args[1]);
System.out.println("A(" + i + ", " + n + ") = " + ackermann(i, n));
}
}
-----------------------
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2 3
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4
i=1 2 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4
i=1 2 3 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3 5
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6
i=1 2 3 4 5 6
i=2 3 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7
i=1 2 3 4 5 6 7
i=2 3 5 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8
i=1 2 3 4 5 6 7 8
i=2 3 5 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9
i=1 2 3 4 5 6 7 8 9
i=2 3 5 7 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
i=2 3 5 7 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11
i=1 2 3 4 5 6 7 8 9 10 11
i=2 3 5 7 9 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11 12
i=1 2 3 4 5 6 7 8 9 10 11 12
i=2 3 5 7 9 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11 12 13
i=1 2 3 4 5 6 7 8 9 10 11 12 13
i=2 3 5 7 9 11 13
i=3 5 13
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 2
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 3
i=1 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 4
i=1 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 5
i=1 5
i=2 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 6
i=1 6
i=2 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 7
i=1 7
i=2 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 8
i=1 8
i=2 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 9
i=1 9
i=2 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 10
i=1 10
i=2 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 11
i=1 11
i=2 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 12
i=1 12
i=2 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 13
i=1 13
i=2 13
i=3 13
/**
* File: Ackermann.java
* Author: Keith Schwarz (htiek@cs.stanford.edu)
*
* An implementation of a variation of Grossman and Zeitman's fast algorithm
* for computing the Ackermann function. This implementation uses O(i) space
* to compute A(i, n), and takes O(A(i, n)) time. The only operation required
* on integers is "increment an integer" and "copy an integer." While this is
* implemented using vanilla ints, it could easily be extended to use BigInteger
* types or the like.
*/
public class Ackermann {
public static int ackermann(int i, int n) {
/* Bounds-check. */
if (i < 0 || n < 0) throw new RuntimeException("Invalid arguments.");
/* Positions array stores what column we're in in each row of
* the table. Initially this is all -1 to signify that we're just
* before the first column.
*/
int[] positions = new int[i + 1];
for (int j = 0; j < positions.length; j++) {
positions[j] = -1;
}
/* Values array stores the value currently in the filled column
* in each row. The value in the zeroth row is set to zero because
* our algorithm works by repeatedly incrementing its value and
* we need it to be the case that A(0, 0) = 1. Since we start off
* with "A(0, -1)" computed, we place a zero there.
*
* All the other values are set to 1. This corresponds to the rule
* that A(i, 0) = A(i - 1, 1), meaning we're waiting for column 1
* to come up in the level below us.
*/
int[] values = new int[i + 1];
for (int j = 1; j < values.length; j++) {
values[j] = 1;
}
/* Run the algorithm until we compute A(i, n), which happens when
* positions[i] == n.
*/
while (positions[i] != n) {
/* Push the value in the bottom row forward and increment it to simulate
* computing the next value of A(0, *).
*/
values[0]++;
positions[0]++;
/* Now, do the ripple. We continue rippling upward while
*
* 1. There's a layer above us to ripple to, and
* 2. The value above us equals our current position.
*/
for (int j = 1; j <= i && positions[j - 1] == values[j]; j++) {
values[j] = values[j - 1]; // Copy the value
positions[j]++; // Shift forward a column
}
}
return values[i];
}
public static void main(String[] args) {
if (args.length != 2) {
System.err.println("Usage: java Ackermann i n");
return;
}
int i = Integer.parseInt(args[0]);
int n = Integer.parseInt(args[1]);
System.out.println("A(" + i + ", " + n + ") = " + ackermann(i, n));
}
}
-----------------------
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2 3
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4
i=1 2 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4
i=1 2 3 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3 5
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6
i=1 2 3 4 5 6
i=2 3 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7
i=1 2 3 4 5 6 7
i=2 3 5 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8
i=1 2 3 4 5 6 7 8
i=2 3 5 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9
i=1 2 3 4 5 6 7 8 9
i=2 3 5 7 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
i=2 3 5 7 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11
i=1 2 3 4 5 6 7 8 9 10 11
i=2 3 5 7 9 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11 12
i=1 2 3 4 5 6 7 8 9 10 11 12
i=2 3 5 7 9 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11 12 13
i=1 2 3 4 5 6 7 8 9 10 11 12 13
i=2 3 5 7 9 11 13
i=3 5 13
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 2
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 3
i=1 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 4
i=1 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 5
i=1 5
i=2 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 6
i=1 6
i=2 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 7
i=1 7
i=2 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 8
i=1 8
i=2 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 9
i=1 9
i=2 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 10
i=1 10
i=2 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 11
i=1 11
i=2 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 12
i=1 12
i=2 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 13
i=1 13
i=2 13
i=3 13
/**
* File: Ackermann.java
* Author: Keith Schwarz (htiek@cs.stanford.edu)
*
* An implementation of a variation of Grossman and Zeitman's fast algorithm
* for computing the Ackermann function. This implementation uses O(i) space
* to compute A(i, n), and takes O(A(i, n)) time. The only operation required
* on integers is "increment an integer" and "copy an integer." While this is
* implemented using vanilla ints, it could easily be extended to use BigInteger
* types or the like.
*/
public class Ackermann {
public static int ackermann(int i, int n) {
/* Bounds-check. */
if (i < 0 || n < 0) throw new RuntimeException("Invalid arguments.");
/* Positions array stores what column we're in in each row of
* the table. Initially this is all -1 to signify that we're just
* before the first column.
*/
int[] positions = new int[i + 1];
for (int j = 0; j < positions.length; j++) {
positions[j] = -1;
}
/* Values array stores the value currently in the filled column
* in each row. The value in the zeroth row is set to zero because
* our algorithm works by repeatedly incrementing its value and
* we need it to be the case that A(0, 0) = 1. Since we start off
* with "A(0, -1)" computed, we place a zero there.
*
* All the other values are set to 1. This corresponds to the rule
* that A(i, 0) = A(i - 1, 1), meaning we're waiting for column 1
* to come up in the level below us.
*/
int[] values = new int[i + 1];
for (int j = 1; j < values.length; j++) {
values[j] = 1;
}
/* Run the algorithm until we compute A(i, n), which happens when
* positions[i] == n.
*/
while (positions[i] != n) {
/* Push the value in the bottom row forward and increment it to simulate
* computing the next value of A(0, *).
*/
values[0]++;
positions[0]++;
/* Now, do the ripple. We continue rippling upward while
*
* 1. There's a layer above us to ripple to, and
* 2. The value above us equals our current position.
*/
for (int j = 1; j <= i && positions[j - 1] == values[j]; j++) {
values[j] = values[j - 1]; // Copy the value
positions[j]++; // Shift forward a column
}
}
return values[i];
}
public static void main(String[] args) {
if (args.length != 2) {
System.err.println("Usage: java Ackermann i n");
return;
}
int i = Integer.parseInt(args[0]);
int n = Integer.parseInt(args[1]);
System.out.println("A(" + i + ", " + n + ") = " + ackermann(i, n));
}
}
-----------------------
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2 3
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4
i=1 2 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4
i=1 2 3 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3 5
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6
i=1 2 3 4 5 6
i=2 3 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7
i=1 2 3 4 5 6 7
i=2 3 5 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8
i=1 2 3 4 5 6 7 8
i=2 3 5 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9
i=1 2 3 4 5 6 7 8 9
i=2 3 5 7 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
i=2 3 5 7 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11
i=1 2 3 4 5 6 7 8 9 10 11
i=2 3 5 7 9 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11 12
i=1 2 3 4 5 6 7 8 9 10 11 12
i=2 3 5 7 9 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11 12 13
i=1 2 3 4 5 6 7 8 9 10 11 12 13
i=2 3 5 7 9 11 13
i=3 5 13
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 2
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 3
i=1 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 4
i=1 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 5
i=1 5
i=2 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 6
i=1 6
i=2 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 7
i=1 7
i=2 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 8
i=1 8
i=2 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 9
i=1 9
i=2 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 10
i=1 10
i=2 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 11
i=1 11
i=2 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 12
i=1 12
i=2 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 13
i=1 13
i=2 13
i=3 13
/**
* File: Ackermann.java
* Author: Keith Schwarz (htiek@cs.stanford.edu)
*
* An implementation of a variation of Grossman and Zeitman's fast algorithm
* for computing the Ackermann function. This implementation uses O(i) space
* to compute A(i, n), and takes O(A(i, n)) time. The only operation required
* on integers is "increment an integer" and "copy an integer." While this is
* implemented using vanilla ints, it could easily be extended to use BigInteger
* types or the like.
*/
public class Ackermann {
public static int ackermann(int i, int n) {
/* Bounds-check. */
if (i < 0 || n < 0) throw new RuntimeException("Invalid arguments.");
/* Positions array stores what column we're in in each row of
* the table. Initially this is all -1 to signify that we're just
* before the first column.
*/
int[] positions = new int[i + 1];
for (int j = 0; j < positions.length; j++) {
positions[j] = -1;
}
/* Values array stores the value currently in the filled column
* in each row. The value in the zeroth row is set to zero because
* our algorithm works by repeatedly incrementing its value and
* we need it to be the case that A(0, 0) = 1. Since we start off
* with "A(0, -1)" computed, we place a zero there.
*
* All the other values are set to 1. This corresponds to the rule
* that A(i, 0) = A(i - 1, 1), meaning we're waiting for column 1
* to come up in the level below us.
*/
int[] values = new int[i + 1];
for (int j = 1; j < values.length; j++) {
values[j] = 1;
}
/* Run the algorithm until we compute A(i, n), which happens when
* positions[i] == n.
*/
while (positions[i] != n) {
/* Push the value in the bottom row forward and increment it to simulate
* computing the next value of A(0, *).
*/
values[0]++;
positions[0]++;
/* Now, do the ripple. We continue rippling upward while
*
* 1. There's a layer above us to ripple to, and
* 2. The value above us equals our current position.
*/
for (int j = 1; j <= i && positions[j - 1] == values[j]; j++) {
values[j] = values[j - 1]; // Copy the value
positions[j]++; // Shift forward a column
}
}
return values[i];
}
public static void main(String[] args) {
if (args.length != 2) {
System.err.println("Usage: java Ackermann i n");
return;
}
int i = Integer.parseInt(args[0]);
int n = Integer.parseInt(args[1]);
System.out.println("A(" + i + ", " + n + ") = " + ackermann(i, n));
}
}
-----------------------
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2 3
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4
i=1 2 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4
i=1 2 3 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3 5
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6
i=1 2 3 4 5 6
i=2 3 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7
i=1 2 3 4 5 6 7
i=2 3 5 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8
i=1 2 3 4 5 6 7 8
i=2 3 5 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9
i=1 2 3 4 5 6 7 8 9
i=2 3 5 7 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
i=2 3 5 7 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11
i=1 2 3 4 5 6 7 8 9 10 11
i=2 3 5 7 9 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11 12
i=1 2 3 4 5 6 7 8 9 10 11 12
i=2 3 5 7 9 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11 12 13
i=1 2 3 4 5 6 7 8 9 10 11 12 13
i=2 3 5 7 9 11 13
i=3 5 13
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 2
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 3
i=1 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 4
i=1 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 5
i=1 5
i=2 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 6
i=1 6
i=2 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 7
i=1 7
i=2 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 8
i=1 8
i=2 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 9
i=1 9
i=2 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 10
i=1 10
i=2 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 11
i=1 11
i=2 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 12
i=1 12
i=2 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 13
i=1 13
i=2 13
i=3 13
/**
* File: Ackermann.java
* Author: Keith Schwarz (htiek@cs.stanford.edu)
*
* An implementation of a variation of Grossman and Zeitman's fast algorithm
* for computing the Ackermann function. This implementation uses O(i) space
* to compute A(i, n), and takes O(A(i, n)) time. The only operation required
* on integers is "increment an integer" and "copy an integer." While this is
* implemented using vanilla ints, it could easily be extended to use BigInteger
* types or the like.
*/
public class Ackermann {
public static int ackermann(int i, int n) {
/* Bounds-check. */
if (i < 0 || n < 0) throw new RuntimeException("Invalid arguments.");
/* Positions array stores what column we're in in each row of
* the table. Initially this is all -1 to signify that we're just
* before the first column.
*/
int[] positions = new int[i + 1];
for (int j = 0; j < positions.length; j++) {
positions[j] = -1;
}
/* Values array stores the value currently in the filled column
* in each row. The value in the zeroth row is set to zero because
* our algorithm works by repeatedly incrementing its value and
* we need it to be the case that A(0, 0) = 1. Since we start off
* with "A(0, -1)" computed, we place a zero there.
*
* All the other values are set to 1. This corresponds to the rule
* that A(i, 0) = A(i - 1, 1), meaning we're waiting for column 1
* to come up in the level below us.
*/
int[] values = new int[i + 1];
for (int j = 1; j < values.length; j++) {
values[j] = 1;
}
/* Run the algorithm until we compute A(i, n), which happens when
* positions[i] == n.
*/
while (positions[i] != n) {
/* Push the value in the bottom row forward and increment it to simulate
* computing the next value of A(0, *).
*/
values[0]++;
positions[0]++;
/* Now, do the ripple. We continue rippling upward while
*
* 1. There's a layer above us to ripple to, and
* 2. The value above us equals our current position.
*/
for (int j = 1; j <= i && positions[j - 1] == values[j]; j++) {
values[j] = values[j - 1]; // Copy the value
positions[j]++; // Shift forward a column
}
}
return values[i];
}
public static void main(String[] args) {
if (args.length != 2) {
System.err.println("Usage: java Ackermann i n");
return;
}
int i = Integer.parseInt(args[0]);
int n = Integer.parseInt(args[1]);
System.out.println("A(" + i + ", " + n + ") = " + ackermann(i, n));
}
}
-----------------------
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2 3
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4
i=1 2 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4
i=1 2 3 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3 5
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6
i=1 2 3 4 5 6
i=2 3 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7
i=1 2 3 4 5 6 7
i=2 3 5 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8
i=1 2 3 4 5 6 7 8
i=2 3 5 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9
i=1 2 3 4 5 6 7 8 9
i=2 3 5 7 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
i=2 3 5 7 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11
i=1 2 3 4 5 6 7 8 9 10 11
i=2 3 5 7 9 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11 12
i=1 2 3 4 5 6 7 8 9 10 11 12
i=2 3 5 7 9 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11 12 13
i=1 2 3 4 5 6 7 8 9 10 11 12 13
i=2 3 5 7 9 11 13
i=3 5 13
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 2
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 3
i=1 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 4
i=1 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 5
i=1 5
i=2 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 6
i=1 6
i=2 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 7
i=1 7
i=2 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 8
i=1 8
i=2 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 9
i=1 9
i=2 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 10
i=1 10
i=2 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 11
i=1 11
i=2 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 12
i=1 12
i=2 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 13
i=1 13
i=2 13
i=3 13
/**
* File: Ackermann.java
* Author: Keith Schwarz (htiek@cs.stanford.edu)
*
* An implementation of a variation of Grossman and Zeitman's fast algorithm
* for computing the Ackermann function. This implementation uses O(i) space
* to compute A(i, n), and takes O(A(i, n)) time. The only operation required
* on integers is "increment an integer" and "copy an integer." While this is
* implemented using vanilla ints, it could easily be extended to use BigInteger
* types or the like.
*/
public class Ackermann {
public static int ackermann(int i, int n) {
/* Bounds-check. */
if (i < 0 || n < 0) throw new RuntimeException("Invalid arguments.");
/* Positions array stores what column we're in in each row of
* the table. Initially this is all -1 to signify that we're just
* before the first column.
*/
int[] positions = new int[i + 1];
for (int j = 0; j < positions.length; j++) {
positions[j] = -1;
}
/* Values array stores the value currently in the filled column
* in each row. The value in the zeroth row is set to zero because
* our algorithm works by repeatedly incrementing its value and
* we need it to be the case that A(0, 0) = 1. Since we start off
* with "A(0, -1)" computed, we place a zero there.
*
* All the other values are set to 1. This corresponds to the rule
* that A(i, 0) = A(i - 1, 1), meaning we're waiting for column 1
* to come up in the level below us.
*/
int[] values = new int[i + 1];
for (int j = 1; j < values.length; j++) {
values[j] = 1;
}
/* Run the algorithm until we compute A(i, n), which happens when
* positions[i] == n.
*/
while (positions[i] != n) {
/* Push the value in the bottom row forward and increment it to simulate
* computing the next value of A(0, *).
*/
values[0]++;
positions[0]++;
/* Now, do the ripple. We continue rippling upward while
*
* 1. There's a layer above us to ripple to, and
* 2. The value above us equals our current position.
*/
for (int j = 1; j <= i && positions[j - 1] == values[j]; j++) {
values[j] = values[j - 1]; // Copy the value
positions[j]++; // Shift forward a column
}
}
return values[i];
}
public static void main(String[] args) {
if (args.length != 2) {
System.err.println("Usage: java Ackermann i n");
return;
}
int i = Integer.parseInt(args[0]);
int n = Integer.parseInt(args[1]);
System.out.println("A(" + i + ", " + n + ") = " + ackermann(i, n));
}
}
-----------------------
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2 3
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4
i=1 2 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4
i=1 2 3 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3 5
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6
i=1 2 3 4 5 6
i=2 3 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7
i=1 2 3 4 5 6 7
i=2 3 5 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8
i=1 2 3 4 5 6 7 8
i=2 3 5 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9
i=1 2 3 4 5 6 7 8 9
i=2 3 5 7 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
i=2 3 5 7 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11
i=1 2 3 4 5 6 7 8 9 10 11
i=2 3 5 7 9 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11 12
i=1 2 3 4 5 6 7 8 9 10 11 12
i=2 3 5 7 9 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11 12 13
i=1 2 3 4 5 6 7 8 9 10 11 12 13
i=2 3 5 7 9 11 13
i=3 5 13
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 2
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 3
i=1 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 4
i=1 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 5
i=1 5
i=2 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 6
i=1 6
i=2 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 7
i=1 7
i=2 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 8
i=1 8
i=2 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 9
i=1 9
i=2 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 10
i=1 10
i=2 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 11
i=1 11
i=2 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 12
i=1 12
i=2 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 13
i=1 13
i=2 13
i=3 13
/**
* File: Ackermann.java
* Author: Keith Schwarz (htiek@cs.stanford.edu)
*
* An implementation of a variation of Grossman and Zeitman's fast algorithm
* for computing the Ackermann function. This implementation uses O(i) space
* to compute A(i, n), and takes O(A(i, n)) time. The only operation required
* on integers is "increment an integer" and "copy an integer." While this is
* implemented using vanilla ints, it could easily be extended to use BigInteger
* types or the like.
*/
public class Ackermann {
public static int ackermann(int i, int n) {
/* Bounds-check. */
if (i < 0 || n < 0) throw new RuntimeException("Invalid arguments.");
/* Positions array stores what column we're in in each row of
* the table. Initially this is all -1 to signify that we're just
* before the first column.
*/
int[] positions = new int[i + 1];
for (int j = 0; j < positions.length; j++) {
positions[j] = -1;
}
/* Values array stores the value currently in the filled column
* in each row. The value in the zeroth row is set to zero because
* our algorithm works by repeatedly incrementing its value and
* we need it to be the case that A(0, 0) = 1. Since we start off
* with "A(0, -1)" computed, we place a zero there.
*
* All the other values are set to 1. This corresponds to the rule
* that A(i, 0) = A(i - 1, 1), meaning we're waiting for column 1
* to come up in the level below us.
*/
int[] values = new int[i + 1];
for (int j = 1; j < values.length; j++) {
values[j] = 1;
}
/* Run the algorithm until we compute A(i, n), which happens when
* positions[i] == n.
*/
while (positions[i] != n) {
/* Push the value in the bottom row forward and increment it to simulate
* computing the next value of A(0, *).
*/
values[0]++;
positions[0]++;
/* Now, do the ripple. We continue rippling upward while
*
* 1. There's a layer above us to ripple to, and
* 2. The value above us equals our current position.
*/
for (int j = 1; j <= i && positions[j - 1] == values[j]; j++) {
values[j] = values[j - 1]; // Copy the value
positions[j]++; // Shift forward a column
}
}
return values[i];
}
public static void main(String[] args) {
if (args.length != 2) {
System.err.println("Usage: java Ackermann i n");
return;
}
int i = Integer.parseInt(args[0]);
int n = Integer.parseInt(args[1]);
System.out.println("A(" + i + ", " + n + ") = " + ackermann(i, n));
}
}
-----------------------
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2 3
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4
i=1 2 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4
i=1 2 3 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3 5
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6
i=1 2 3 4 5 6
i=2 3 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7
i=1 2 3 4 5 6 7
i=2 3 5 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8
i=1 2 3 4 5 6 7 8
i=2 3 5 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9
i=1 2 3 4 5 6 7 8 9
i=2 3 5 7 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
i=2 3 5 7 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11
i=1 2 3 4 5 6 7 8 9 10 11
i=2 3 5 7 9 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11 12
i=1 2 3 4 5 6 7 8 9 10 11 12
i=2 3 5 7 9 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11 12 13
i=1 2 3 4 5 6 7 8 9 10 11 12 13
i=2 3 5 7 9 11 13
i=3 5 13
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 2
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 3
i=1 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 4
i=1 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 5
i=1 5
i=2 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 6
i=1 6
i=2 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 7
i=1 7
i=2 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 8
i=1 8
i=2 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 9
i=1 9
i=2 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 10
i=1 10
i=2 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 11
i=1 11
i=2 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 12
i=1 12
i=2 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 13
i=1 13
i=2 13
i=3 13
/**
* File: Ackermann.java
* Author: Keith Schwarz (htiek@cs.stanford.edu)
*
* An implementation of a variation of Grossman and Zeitman's fast algorithm
* for computing the Ackermann function. This implementation uses O(i) space
* to compute A(i, n), and takes O(A(i, n)) time. The only operation required
* on integers is "increment an integer" and "copy an integer." While this is
* implemented using vanilla ints, it could easily be extended to use BigInteger
* types or the like.
*/
public class Ackermann {
public static int ackermann(int i, int n) {
/* Bounds-check. */
if (i < 0 || n < 0) throw new RuntimeException("Invalid arguments.");
/* Positions array stores what column we're in in each row of
* the table. Initially this is all -1 to signify that we're just
* before the first column.
*/
int[] positions = new int[i + 1];
for (int j = 0; j < positions.length; j++) {
positions[j] = -1;
}
/* Values array stores the value currently in the filled column
* in each row. The value in the zeroth row is set to zero because
* our algorithm works by repeatedly incrementing its value and
* we need it to be the case that A(0, 0) = 1. Since we start off
* with "A(0, -1)" computed, we place a zero there.
*
* All the other values are set to 1. This corresponds to the rule
* that A(i, 0) = A(i - 1, 1), meaning we're waiting for column 1
* to come up in the level below us.
*/
int[] values = new int[i + 1];
for (int j = 1; j < values.length; j++) {
values[j] = 1;
}
/* Run the algorithm until we compute A(i, n), which happens when
* positions[i] == n.
*/
while (positions[i] != n) {
/* Push the value in the bottom row forward and increment it to simulate
* computing the next value of A(0, *).
*/
values[0]++;
positions[0]++;
/* Now, do the ripple. We continue rippling upward while
*
* 1. There's a layer above us to ripple to, and
* 2. The value above us equals our current position.
*/
for (int j = 1; j <= i && positions[j - 1] == values[j]; j++) {
values[j] = values[j - 1]; // Copy the value
positions[j]++; // Shift forward a column
}
}
return values[i];
}
public static void main(String[] args) {
if (args.length != 2) {
System.err.println("Usage: java Ackermann i n");
return;
}
int i = Integer.parseInt(args[0]);
int n = Integer.parseInt(args[1]);
System.out.println("A(" + i + ", " + n + ") = " + ackermann(i, n));
}
}
-----------------------
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2 3
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4
i=1 2 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4
i=1 2 3 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3 5
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6
i=1 2 3 4 5 6
i=2 3 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7
i=1 2 3 4 5 6 7
i=2 3 5 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8
i=1 2 3 4 5 6 7 8
i=2 3 5 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9
i=1 2 3 4 5 6 7 8 9
i=2 3 5 7 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
i=2 3 5 7 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11
i=1 2 3 4 5 6 7 8 9 10 11
i=2 3 5 7 9 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11 12
i=1 2 3 4 5 6 7 8 9 10 11 12
i=2 3 5 7 9 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11 12 13
i=1 2 3 4 5 6 7 8 9 10 11 12 13
i=2 3 5 7 9 11 13
i=3 5 13
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 2
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 3
i=1 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 4
i=1 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 5
i=1 5
i=2 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 6
i=1 6
i=2 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 7
i=1 7
i=2 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 8
i=1 8
i=2 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 9
i=1 9
i=2 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 10
i=1 10
i=2 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 11
i=1 11
i=2 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 12
i=1 12
i=2 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 13
i=1 13
i=2 13
i=3 13
/**
* File: Ackermann.java
* Author: Keith Schwarz (htiek@cs.stanford.edu)
*
* An implementation of a variation of Grossman and Zeitman's fast algorithm
* for computing the Ackermann function. This implementation uses O(i) space
* to compute A(i, n), and takes O(A(i, n)) time. The only operation required
* on integers is "increment an integer" and "copy an integer." While this is
* implemented using vanilla ints, it could easily be extended to use BigInteger
* types or the like.
*/
public class Ackermann {
public static int ackermann(int i, int n) {
/* Bounds-check. */
if (i < 0 || n < 0) throw new RuntimeException("Invalid arguments.");
/* Positions array stores what column we're in in each row of
* the table. Initially this is all -1 to signify that we're just
* before the first column.
*/
int[] positions = new int[i + 1];
for (int j = 0; j < positions.length; j++) {
positions[j] = -1;
}
/* Values array stores the value currently in the filled column
* in each row. The value in the zeroth row is set to zero because
* our algorithm works by repeatedly incrementing its value and
* we need it to be the case that A(0, 0) = 1. Since we start off
* with "A(0, -1)" computed, we place a zero there.
*
* All the other values are set to 1. This corresponds to the rule
* that A(i, 0) = A(i - 1, 1), meaning we're waiting for column 1
* to come up in the level below us.
*/
int[] values = new int[i + 1];
for (int j = 1; j < values.length; j++) {
values[j] = 1;
}
/* Run the algorithm until we compute A(i, n), which happens when
* positions[i] == n.
*/
while (positions[i] != n) {
/* Push the value in the bottom row forward and increment it to simulate
* computing the next value of A(0, *).
*/
values[0]++;
positions[0]++;
/* Now, do the ripple. We continue rippling upward while
*
* 1. There's a layer above us to ripple to, and
* 2. The value above us equals our current position.
*/
for (int j = 1; j <= i && positions[j - 1] == values[j]; j++) {
values[j] = values[j - 1]; // Copy the value
positions[j]++; // Shift forward a column
}
}
return values[i];
}
public static void main(String[] args) {
if (args.length != 2) {
System.err.println("Usage: java Ackermann i n");
return;
}
int i = Integer.parseInt(args[0]);
int n = Integer.parseInt(args[1]);
System.out.println("A(" + i + ", " + n + ") = " + ackermann(i, n));
}
}
-----------------------
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2 3
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4
i=1 2 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4
i=1 2 3 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3 5
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6
i=1 2 3 4 5 6
i=2 3 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7
i=1 2 3 4 5 6 7
i=2 3 5 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8
i=1 2 3 4 5 6 7 8
i=2 3 5 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9
i=1 2 3 4 5 6 7 8 9
i=2 3 5 7 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
i=2 3 5 7 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11
i=1 2 3 4 5 6 7 8 9 10 11
i=2 3 5 7 9 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11 12
i=1 2 3 4 5 6 7 8 9 10 11 12
i=2 3 5 7 9 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11 12 13
i=1 2 3 4 5 6 7 8 9 10 11 12 13
i=2 3 5 7 9 11 13
i=3 5 13
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 2
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 3
i=1 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 4
i=1 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 5
i=1 5
i=2 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 6
i=1 6
i=2 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 7
i=1 7
i=2 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 8
i=1 8
i=2 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 9
i=1 9
i=2 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 10
i=1 10
i=2 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 11
i=1 11
i=2 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 12
i=1 12
i=2 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 13
i=1 13
i=2 13
i=3 13
/**
* File: Ackermann.java
* Author: Keith Schwarz (htiek@cs.stanford.edu)
*
* An implementation of a variation of Grossman and Zeitman's fast algorithm
* for computing the Ackermann function. This implementation uses O(i) space
* to compute A(i, n), and takes O(A(i, n)) time. The only operation required
* on integers is "increment an integer" and "copy an integer." While this is
* implemented using vanilla ints, it could easily be extended to use BigInteger
* types or the like.
*/
public class Ackermann {
public static int ackermann(int i, int n) {
/* Bounds-check. */
if (i < 0 || n < 0) throw new RuntimeException("Invalid arguments.");
/* Positions array stores what column we're in in each row of
* the table. Initially this is all -1 to signify that we're just
* before the first column.
*/
int[] positions = new int[i + 1];
for (int j = 0; j < positions.length; j++) {
positions[j] = -1;
}
/* Values array stores the value currently in the filled column
* in each row. The value in the zeroth row is set to zero because
* our algorithm works by repeatedly incrementing its value and
* we need it to be the case that A(0, 0) = 1. Since we start off
* with "A(0, -1)" computed, we place a zero there.
*
* All the other values are set to 1. This corresponds to the rule
* that A(i, 0) = A(i - 1, 1), meaning we're waiting for column 1
* to come up in the level below us.
*/
int[] values = new int[i + 1];
for (int j = 1; j < values.length; j++) {
values[j] = 1;
}
/* Run the algorithm until we compute A(i, n), which happens when
* positions[i] == n.
*/
while (positions[i] != n) {
/* Push the value in the bottom row forward and increment it to simulate
* computing the next value of A(0, *).
*/
values[0]++;
positions[0]++;
/* Now, do the ripple. We continue rippling upward while
*
* 1. There's a layer above us to ripple to, and
* 2. The value above us equals our current position.
*/
for (int j = 1; j <= i && positions[j - 1] == values[j]; j++) {
values[j] = values[j - 1]; // Copy the value
positions[j]++; // Shift forward a column
}
}
return values[i];
}
public static void main(String[] args) {
if (args.length != 2) {
System.err.println("Usage: java Ackermann i n");
return;
}
int i = Integer.parseInt(args[0]);
int n = Integer.parseInt(args[1]);
System.out.println("A(" + i + ", " + n + ") = " + ackermann(i, n));
}
}
-----------------------
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2 3
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4
i=1 2 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4
i=1 2 3 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3 5
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6
i=1 2 3 4 5 6
i=2 3 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7
i=1 2 3 4 5 6 7
i=2 3 5 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8
i=1 2 3 4 5 6 7 8
i=2 3 5 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9
i=1 2 3 4 5 6 7 8 9
i=2 3 5 7 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
i=2 3 5 7 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11
i=1 2 3 4 5 6 7 8 9 10 11
i=2 3 5 7 9 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11 12
i=1 2 3 4 5 6 7 8 9 10 11 12
i=2 3 5 7 9 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11 12 13
i=1 2 3 4 5 6 7 8 9 10 11 12 13
i=2 3 5 7 9 11 13
i=3 5 13
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 2
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 3
i=1 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 4
i=1 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 5
i=1 5
i=2 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 6
i=1 6
i=2 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 7
i=1 7
i=2 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 8
i=1 8
i=2 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 9
i=1 9
i=2 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 10
i=1 10
i=2 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 11
i=1 11
i=2 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 12
i=1 12
i=2 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 13
i=1 13
i=2 13
i=3 13
/**
* File: Ackermann.java
* Author: Keith Schwarz (htiek@cs.stanford.edu)
*
* An implementation of a variation of Grossman and Zeitman's fast algorithm
* for computing the Ackermann function. This implementation uses O(i) space
* to compute A(i, n), and takes O(A(i, n)) time. The only operation required
* on integers is "increment an integer" and "copy an integer." While this is
* implemented using vanilla ints, it could easily be extended to use BigInteger
* types or the like.
*/
public class Ackermann {
public static int ackermann(int i, int n) {
/* Bounds-check. */
if (i < 0 || n < 0) throw new RuntimeException("Invalid arguments.");
/* Positions array stores what column we're in in each row of
* the table. Initially this is all -1 to signify that we're just
* before the first column.
*/
int[] positions = new int[i + 1];
for (int j = 0; j < positions.length; j++) {
positions[j] = -1;
}
/* Values array stores the value currently in the filled column
* in each row. The value in the zeroth row is set to zero because
* our algorithm works by repeatedly incrementing its value and
* we need it to be the case that A(0, 0) = 1. Since we start off
* with "A(0, -1)" computed, we place a zero there.
*
* All the other values are set to 1. This corresponds to the rule
* that A(i, 0) = A(i - 1, 1), meaning we're waiting for column 1
* to come up in the level below us.
*/
int[] values = new int[i + 1];
for (int j = 1; j < values.length; j++) {
values[j] = 1;
}
/* Run the algorithm until we compute A(i, n), which happens when
* positions[i] == n.
*/
while (positions[i] != n) {
/* Push the value in the bottom row forward and increment it to simulate
* computing the next value of A(0, *).
*/
values[0]++;
positions[0]++;
/* Now, do the ripple. We continue rippling upward while
*
* 1. There's a layer above us to ripple to, and
* 2. The value above us equals our current position.
*/
for (int j = 1; j <= i && positions[j - 1] == values[j]; j++) {
values[j] = values[j - 1]; // Copy the value
positions[j]++; // Shift forward a column
}
}
return values[i];
}
public static void main(String[] args) {
if (args.length != 2) {
System.err.println("Usage: java Ackermann i n");
return;
}
int i = Integer.parseInt(args[0]);
int n = Integer.parseInt(args[1]);
System.out.println("A(" + i + ", " + n + ") = " + ackermann(i, n));
}
}
-----------------------
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2 3
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4
i=1 2 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4
i=1 2 3 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3 5
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6
i=1 2 3 4 5 6
i=2 3 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7
i=1 2 3 4 5 6 7
i=2 3 5 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8
i=1 2 3 4 5 6 7 8
i=2 3 5 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9
i=1 2 3 4 5 6 7 8 9
i=2 3 5 7 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
i=2 3 5 7 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11
i=1 2 3 4 5 6 7 8 9 10 11
i=2 3 5 7 9 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11 12
i=1 2 3 4 5 6 7 8 9 10 11 12
i=2 3 5 7 9 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11 12 13
i=1 2 3 4 5 6 7 8 9 10 11 12 13
i=2 3 5 7 9 11 13
i=3 5 13
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 2
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 3
i=1 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 4
i=1 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 5
i=1 5
i=2 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 6
i=1 6
i=2 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 7
i=1 7
i=2 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 8
i=1 8
i=2 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 9
i=1 9
i=2 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 10
i=1 10
i=2 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 11
i=1 11
i=2 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 12
i=1 12
i=2 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 13
i=1 13
i=2 13
i=3 13
/**
* File: Ackermann.java
* Author: Keith Schwarz (htiek@cs.stanford.edu)
*
* An implementation of a variation of Grossman and Zeitman's fast algorithm
* for computing the Ackermann function. This implementation uses O(i) space
* to compute A(i, n), and takes O(A(i, n)) time. The only operation required
* on integers is "increment an integer" and "copy an integer." While this is
* implemented using vanilla ints, it could easily be extended to use BigInteger
* types or the like.
*/
public class Ackermann {
public static int ackermann(int i, int n) {
/* Bounds-check. */
if (i < 0 || n < 0) throw new RuntimeException("Invalid arguments.");
/* Positions array stores what column we're in in each row of
* the table. Initially this is all -1 to signify that we're just
* before the first column.
*/
int[] positions = new int[i + 1];
for (int j = 0; j < positions.length; j++) {
positions[j] = -1;
}
/* Values array stores the value currently in the filled column
* in each row. The value in the zeroth row is set to zero because
* our algorithm works by repeatedly incrementing its value and
* we need it to be the case that A(0, 0) = 1. Since we start off
* with "A(0, -1)" computed, we place a zero there.
*
* All the other values are set to 1. This corresponds to the rule
* that A(i, 0) = A(i - 1, 1), meaning we're waiting for column 1
* to come up in the level below us.
*/
int[] values = new int[i + 1];
for (int j = 1; j < values.length; j++) {
values[j] = 1;
}
/* Run the algorithm until we compute A(i, n), which happens when
* positions[i] == n.
*/
while (positions[i] != n) {
/* Push the value in the bottom row forward and increment it to simulate
* computing the next value of A(0, *).
*/
values[0]++;
positions[0]++;
/* Now, do the ripple. We continue rippling upward while
*
* 1. There's a layer above us to ripple to, and
* 2. The value above us equals our current position.
*/
for (int j = 1; j <= i && positions[j - 1] == values[j]; j++) {
values[j] = values[j - 1]; // Copy the value
positions[j]++; // Shift forward a column
}
}
return values[i];
}
public static void main(String[] args) {
if (args.length != 2) {
System.err.println("Usage: java Ackermann i n");
return;
}
int i = Integer.parseInt(args[0]);
int n = Integer.parseInt(args[1]);
System.out.println("A(" + i + ", " + n + ") = " + ackermann(i, n));
}
}
-----------------------
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2 3
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4
i=1 2 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4
i=1 2 3 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3 5
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6
i=1 2 3 4 5 6
i=2 3 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7
i=1 2 3 4 5 6 7
i=2 3 5 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8
i=1 2 3 4 5 6 7 8
i=2 3 5 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9
i=1 2 3 4 5 6 7 8 9
i=2 3 5 7 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
i=2 3 5 7 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11
i=1 2 3 4 5 6 7 8 9 10 11
i=2 3 5 7 9 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11 12
i=1 2 3 4 5 6 7 8 9 10 11 12
i=2 3 5 7 9 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11 12 13
i=1 2 3 4 5 6 7 8 9 10 11 12 13
i=2 3 5 7 9 11 13
i=3 5 13
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 2
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 3
i=1 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 4
i=1 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 5
i=1 5
i=2 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 6
i=1 6
i=2 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 7
i=1 7
i=2 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 8
i=1 8
i=2 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 9
i=1 9
i=2 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 10
i=1 10
i=2 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 11
i=1 11
i=2 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 12
i=1 12
i=2 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 13
i=1 13
i=2 13
i=3 13
/**
* File: Ackermann.java
* Author: Keith Schwarz (htiek@cs.stanford.edu)
*
* An implementation of a variation of Grossman and Zeitman's fast algorithm
* for computing the Ackermann function. This implementation uses O(i) space
* to compute A(i, n), and takes O(A(i, n)) time. The only operation required
* on integers is "increment an integer" and "copy an integer." While this is
* implemented using vanilla ints, it could easily be extended to use BigInteger
* types or the like.
*/
public class Ackermann {
public static int ackermann(int i, int n) {
/* Bounds-check. */
if (i < 0 || n < 0) throw new RuntimeException("Invalid arguments.");
/* Positions array stores what column we're in in each row of
* the table. Initially this is all -1 to signify that we're just
* before the first column.
*/
int[] positions = new int[i + 1];
for (int j = 0; j < positions.length; j++) {
positions[j] = -1;
}
/* Values array stores the value currently in the filled column
* in each row. The value in the zeroth row is set to zero because
* our algorithm works by repeatedly incrementing its value and
* we need it to be the case that A(0, 0) = 1. Since we start off
* with "A(0, -1)" computed, we place a zero there.
*
* All the other values are set to 1. This corresponds to the rule
* that A(i, 0) = A(i - 1, 1), meaning we're waiting for column 1
* to come up in the level below us.
*/
int[] values = new int[i + 1];
for (int j = 1; j < values.length; j++) {
values[j] = 1;
}
/* Run the algorithm until we compute A(i, n), which happens when
* positions[i] == n.
*/
while (positions[i] != n) {
/* Push the value in the bottom row forward and increment it to simulate
* computing the next value of A(0, *).
*/
values[0]++;
positions[0]++;
/* Now, do the ripple. We continue rippling upward while
*
* 1. There's a layer above us to ripple to, and
* 2. The value above us equals our current position.
*/
for (int j = 1; j <= i && positions[j - 1] == values[j]; j++) {
values[j] = values[j - 1]; // Copy the value
positions[j]++; // Shift forward a column
}
}
return values[i];
}
public static void main(String[] args) {
if (args.length != 2) {
System.err.println("Usage: java Ackermann i n");
return;
}
int i = Integer.parseInt(args[0]);
int n = Integer.parseInt(args[1]);
System.out.println("A(" + i + ", " + n + ") = " + ackermann(i, n));
}
}
-----------------------
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2 3
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4
i=1 2 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4
i=1 2 3 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3 5
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6
i=1 2 3 4 5 6
i=2 3 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7
i=1 2 3 4 5 6 7
i=2 3 5 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8
i=1 2 3 4 5 6 7 8
i=2 3 5 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9
i=1 2 3 4 5 6 7 8 9
i=2 3 5 7 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
i=2 3 5 7 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11
i=1 2 3 4 5 6 7 8 9 10 11
i=2 3 5 7 9 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11 12
i=1 2 3 4 5 6 7 8 9 10 11 12
i=2 3 5 7 9 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11 12 13
i=1 2 3 4 5 6 7 8 9 10 11 12 13
i=2 3 5 7 9 11 13
i=3 5 13
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 2
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 3
i=1 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 4
i=1 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 5
i=1 5
i=2 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 6
i=1 6
i=2 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 7
i=1 7
i=2 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 8
i=1 8
i=2 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 9
i=1 9
i=2 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 10
i=1 10
i=2 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 11
i=1 11
i=2 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 12
i=1 12
i=2 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 13
i=1 13
i=2 13
i=3 13
/**
* File: Ackermann.java
* Author: Keith Schwarz (htiek@cs.stanford.edu)
*
* An implementation of a variation of Grossman and Zeitman's fast algorithm
* for computing the Ackermann function. This implementation uses O(i) space
* to compute A(i, n), and takes O(A(i, n)) time. The only operation required
* on integers is "increment an integer" and "copy an integer." While this is
* implemented using vanilla ints, it could easily be extended to use BigInteger
* types or the like.
*/
public class Ackermann {
public static int ackermann(int i, int n) {
/* Bounds-check. */
if (i < 0 || n < 0) throw new RuntimeException("Invalid arguments.");
/* Positions array stores what column we're in in each row of
* the table. Initially this is all -1 to signify that we're just
* before the first column.
*/
int[] positions = new int[i + 1];
for (int j = 0; j < positions.length; j++) {
positions[j] = -1;
}
/* Values array stores the value currently in the filled column
* in each row. The value in the zeroth row is set to zero because
* our algorithm works by repeatedly incrementing its value and
* we need it to be the case that A(0, 0) = 1. Since we start off
* with "A(0, -1)" computed, we place a zero there.
*
* All the other values are set to 1. This corresponds to the rule
* that A(i, 0) = A(i - 1, 1), meaning we're waiting for column 1
* to come up in the level below us.
*/
int[] values = new int[i + 1];
for (int j = 1; j < values.length; j++) {
values[j] = 1;
}
/* Run the algorithm until we compute A(i, n), which happens when
* positions[i] == n.
*/
while (positions[i] != n) {
/* Push the value in the bottom row forward and increment it to simulate
* computing the next value of A(0, *).
*/
values[0]++;
positions[0]++;
/* Now, do the ripple. We continue rippling upward while
*
* 1. There's a layer above us to ripple to, and
* 2. The value above us equals our current position.
*/
for (int j = 1; j <= i && positions[j - 1] == values[j]; j++) {
values[j] = values[j - 1]; // Copy the value
positions[j]++; // Shift forward a column
}
}
return values[i];
}
public static void main(String[] args) {
if (args.length != 2) {
System.err.println("Usage: java Ackermann i n");
return;
}
int i = Integer.parseInt(args[0]);
int n = Integer.parseInt(args[1]);
System.out.println("A(" + i + ", " + n + ") = " + ackermann(i, n));
}
}
-----------------------
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2 3
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4
i=1 2 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4
i=1 2 3 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3 5
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6
i=1 2 3 4 5 6
i=2 3 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7
i=1 2 3 4 5 6 7
i=2 3 5 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8
i=1 2 3 4 5 6 7 8
i=2 3 5 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9
i=1 2 3 4 5 6 7 8 9
i=2 3 5 7 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
i=2 3 5 7 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11
i=1 2 3 4 5 6 7 8 9 10 11
i=2 3 5 7 9 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11 12
i=1 2 3 4 5 6 7 8 9 10 11 12
i=2 3 5 7 9 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11 12 13
i=1 2 3 4 5 6 7 8 9 10 11 12 13
i=2 3 5 7 9 11 13
i=3 5 13
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 2
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 3
i=1 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 4
i=1 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 5
i=1 5
i=2 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 6
i=1 6
i=2 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 7
i=1 7
i=2 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 8
i=1 8
i=2 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 9
i=1 9
i=2 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 10
i=1 10
i=2 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 11
i=1 11
i=2 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 12
i=1 12
i=2 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 13
i=1 13
i=2 13
i=3 13
/**
* File: Ackermann.java
* Author: Keith Schwarz (htiek@cs.stanford.edu)
*
* An implementation of a variation of Grossman and Zeitman's fast algorithm
* for computing the Ackermann function. This implementation uses O(i) space
* to compute A(i, n), and takes O(A(i, n)) time. The only operation required
* on integers is "increment an integer" and "copy an integer." While this is
* implemented using vanilla ints, it could easily be extended to use BigInteger
* types or the like.
*/
public class Ackermann {
public static int ackermann(int i, int n) {
/* Bounds-check. */
if (i < 0 || n < 0) throw new RuntimeException("Invalid arguments.");
/* Positions array stores what column we're in in each row of
* the table. Initially this is all -1 to signify that we're just
* before the first column.
*/
int[] positions = new int[i + 1];
for (int j = 0; j < positions.length; j++) {
positions[j] = -1;
}
/* Values array stores the value currently in the filled column
* in each row. The value in the zeroth row is set to zero because
* our algorithm works by repeatedly incrementing its value and
* we need it to be the case that A(0, 0) = 1. Since we start off
* with "A(0, -1)" computed, we place a zero there.
*
* All the other values are set to 1. This corresponds to the rule
* that A(i, 0) = A(i - 1, 1), meaning we're waiting for column 1
* to come up in the level below us.
*/
int[] values = new int[i + 1];
for (int j = 1; j < values.length; j++) {
values[j] = 1;
}
/* Run the algorithm until we compute A(i, n), which happens when
* positions[i] == n.
*/
while (positions[i] != n) {
/* Push the value in the bottom row forward and increment it to simulate
* computing the next value of A(0, *).
*/
values[0]++;
positions[0]++;
/* Now, do the ripple. We continue rippling upward while
*
* 1. There's a layer above us to ripple to, and
* 2. The value above us equals our current position.
*/
for (int j = 1; j <= i && positions[j - 1] == values[j]; j++) {
values[j] = values[j - 1]; // Copy the value
positions[j]++; // Shift forward a column
}
}
return values[i];
}
public static void main(String[] args) {
if (args.length != 2) {
System.err.println("Usage: java Ackermann i n");
return;
}
int i = Integer.parseInt(args[0]);
int n = Integer.parseInt(args[1]);
System.out.println("A(" + i + ", " + n + ") = " + ackermann(i, n));
}
}
-----------------------
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2 3
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3
i=1 2 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4
i=1 2 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4
i=1 2 3 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3 5
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5
i=1 2 3 4 5
i=2 3 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6
i=1 2 3 4 5 6
i=2 3 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7
i=1 2 3 4 5 6 7
i=2 3 5 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8
i=1 2 3 4 5 6 7 8
i=2 3 5 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9
i=1 2 3 4 5 6 7 8 9
i=2 3 5 7 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
i=2 3 5 7 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11
i=1 2 3 4 5 6 7 8 9 10 11
i=2 3 5 7 9 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11 12
i=1 2 3 4 5 6 7 8 9 10 11 12
i=2 3 5 7 9 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1 2 3 4 5 6 7 8 9 10 11 12 13
i=1 2 3 4 5 6 7 8 9 10 11 12 13
i=2 3 5 7 9 11 13
i=3 5 13
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 1
i=1
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 2
i=1 2
i=2
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 3
i=1 3
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 4
i=1 4
i=2 3
i=3
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 5
i=1 5
i=2 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 6
i=1 6
i=2 5
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 7
i=1 7
i=2 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 8
i=1 8
i=2 7
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 9
i=1 9
i=2 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 10
i=1 10
i=2 9
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 11
i=1 11
i=2 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 12
i=1 12
i=2 11
i=3 5
n=0 n=1 n=2 n=3 n=4 n=5 n=6 n=7 n=8 n=9 n=10 n=11 n=12
i=0 13
i=1 13
i=2 13
i=3 13
/**
* File: Ackermann.java
* Author: Keith Schwarz (htiek@cs.stanford.edu)
*
* An implementation of a variation of Grossman and Zeitman's fast algorithm
* for computing the Ackermann function. This implementation uses O(i) space
* to compute A(i, n), and takes O(A(i, n)) time. The only operation required
* on integers is "increment an integer" and "copy an integer." While this is
* implemented using vanilla ints, it could easily be extended to use BigInteger
* types or the like.
*/
public class Ackermann {
public static int ackermann(int i, int n) {
/* Bounds-check. */
if (i < 0 || n < 0) throw new RuntimeException("Invalid arguments.");
/* Positions array stores what column we're in in each row of
* the table. Initially this is all -1 to signify that we're just
* before the first column.
*/
int[] positions = new int[i + 1];
for (int j = 0; j < positions.length; j++) {
positions[j] = -1;
}
/* Values array stores the value currently in the filled column
* in each row. The value in the zeroth row is set to zero because
* our algorithm works by repeatedly incrementing its value and
* we need it to be the case that A(0, 0) = 1. Since we start off
* with "A(0, -1)" computed, we place a zero there.
*
* All the other values are set to 1. This corresponds to the rule
* that A(i, 0) = A(i - 1, 1), meaning we're waiting for column 1
* to come up in the level below us.
*/
int[] values = new int[i + 1];
for (int j = 1; j < values.length; j++) {
values[j] = 1;
}
/* Run the algorithm until we compute A(i, n), which happens when
* positions[i] == n.
*/
while (positions[i] != n) {
/* Push the value in the bottom row forward and increment it to simulate
* computing the next value of A(0, *).
*/
values[0]++;
positions[0]++;
/* Now, do the ripple. We continue rippling upward while
*
* 1. There's a layer above us to ripple to, and
* 2. The value above us equals our current position.
*/
for (int j = 1; j <= i && positions[j - 1] == values[j]; j++) {
values[j] = values[j - 1]; // Copy the value
positions[j]++; // Shift forward a column
}
}
return values[i];
}
public static void main(String[] args) {
if (args.length != 2) {
System.err.println("Usage: java Ackermann i n");
return;
}
int i = Integer.parseInt(args[0]);
int n = Integer.parseInt(args[1]);
System.out.println("A(" + i + ", " + n + ") = " + ackermann(i, n));
}
}
xcrun: error: SDK "iphoneos" cannot be located
sudo xcode-select --switch /Applications/Xcode.app
QUESTION
Segmented far pointer allocation in 16bit x86 MS-DOS real mode
Asked 2022-Apr-03 at 08:07I'm trying to get my head around programming real mode MS-DOS in C. Using some old books on game programming as a starting point. The source code in the book is written for Microsoft C, but I'm trying to get it to compile under OpenWatcom v2. I've run into a problem early on, when trying to access a pointer to the start of VGA video memory.
#include <stdio.h>
#include <dos.h>
void Set_Video_Mode(int mode) {
union REGS inregs, outregs;
inregs.h.ah = 0;
inregs.h.al = (unsigned char) mode;
int86(0x10, &inregs, &outregs);
}
int main(void)
{
Set_Video_Mode(0x13);
//the following line throws an error, without it the code compiles and runs
char far *video_buffer = (char far *)0xA0000000L;
while (!kbhit()) { };
Set_Video_Mode(0x03);
return 0;
}
It's the far pointer assignment that throws the following errors:
VGA.C(33): Error! E1077: Missing '}'
VGA.C(33): Warning! W107: Missing return value for function 'main'
VGA.C(36): Error! E1099: Statement must be inside function. Probable cause: missing {
Which is kind of baffling, and seems like a macro definition gone wrong, or something...
When I try the code from the Wikipedia article on far pointers, with the same compiler:
#include <stdio.h>
int main() {
char far *p = (char far *)0x55550005;
char far *q = (char far *)0x53332225;
*p = 80;
(*p)++;
printf("%d", *q);
return 0;
}
It compiles.
The compile command is wcl -bcl=dos source.c
in both cases.
So I'm kind of stumped now, and can't seem to pinpoint the problem. I'm on the verge of throwing a few asterisks and brackets at random places to see if it sticks somewhere...
ANSWER
Answered 2022-Apr-03 at 07:23It appears your OpenWatcom C compiler is defaulting to using C89. In C89 variable declarations must be at the beginning of a block scope. In your case all your code and data is at function scope, so the variable has to be declared at the beginning of main
before the code.
Moving the variable declaration this way should be C89 compatible:
int main(void)
{
char far *video_buffer = (char far *)0xA0000000L;
Set_Video_Mode(0x13);
while (!kbhit()) { };
Set_Video_Mode(0x03);
return 0;
}
If using OpenWatcom 2.0 as you suggest you are, you should be able to compile with C99 mode by adding the option -za99
to the wcl
options. In C99 you can place variable declarations in places other than top of block scope.
When compiling as C89, Watcom extended C89 to allow C++ style comments the same way C99 supports it. This behaviour seem to be documented as:
The Open Watcom C/16 and C/32 compilers support an extension for comments. The symbol // can be used at any point in a physical source line (except inside a character constant or string literal). Any characters from the // to the end of the line are treated as comment characters. The comment is terminated by the end of the line.
I agree with the assessment that had the C++ style comments not been allowed, the compiler would have given a much better picture of what the real problem was. I too was fooled at first and it didn't occur to me right away that it was being compiled as C89 code. I had assumed since the //
was accepted that it must have been C99.
Community Discussions, Code Snippets contain sources that include Stack Exchange Network
No vulnerabilities reported
Save this library and start creating your kit
Explore Related Topics
Save this library and start creating your kit