Commit bcf1eda1 authored by HankG's avatar HankG

Added straight port fannkuchredux

parent 60718910
/*
* The Computer Language Benchmarks Game
* http://benchmarksgame.alioth.debian.org/
*
* Based on Java version (#3 by Oleg Mazurov
* Contributed by Hank Grabowski
*
*/
import java.util.concurrent.atomic.AtomicInteger
class fannkuchredux : Runnable {
internal var p: IntArray = IntArray(0)
internal var pp: IntArray = IntArray(0)
internal var count: IntArray = IntArray(0)
internal fun print() {
for (i in p.indices) {
print(p[i] + 1)
}
println()
}
internal fun firstPermutation(idx: Int) {
var idx = idx
for (i in p.indices) {
p[i] = i
}
for (i in count.size - 1 downTo 1) {
val d = idx / Fact!![i]
count[i] = d
idx = idx % Fact!![i]
System.arraycopy(p, 0, pp, 0, i + 1)
for (j in 0..i) {
p[j] = if (j + d <= i) pp[j + d] else pp[j + d - i - 1]
}
}
}
internal fun nextPermutation(): Boolean {
var first = p[1]
p[1] = p[0]
p[0] = first
var i = 1
while (++count[i] > i) {
count[i++] = 0
p[0] = p[1]
val next = p[0]
for (j in 1..i - 1) {
p[j] = p[j + 1]
}
p[i] = first
first = next
}
return true
}
internal fun countFlips(): Int {
var flips = 1
var first = p[0]
if (p[first] != 0) {
System.arraycopy(p, 0, pp, 0, pp.size)
do {
++flips
var lo = 1
var hi = first - 1
while (lo < hi) {
val t = pp[lo]
pp[lo] = pp[hi]
pp[hi] = t
++lo
--hi
}
val t = pp[first]
pp[first] = first
first = t
} while (pp[first] != 0)
}
return flips
}
internal fun runTask(task: Int) {
val idxMin = task * CHUNKSZ
val idxMax = Math.min(Fact!![n], idxMin + CHUNKSZ)
firstPermutation(idxMin)
var maxflips = 1
var chksum = 0
var i = idxMin
while (true) {
if (p[0] != 0) {
val flips = countFlips()
maxflips = Math.max(maxflips, flips)
chksum += if (i % 2 == 0) flips else -flips
}
if (++i == idxMax) {
break
}
nextPermutation()
}
maxFlips!![task] = maxflips
chkSums!![task] = chksum
}
override fun run() {
p = IntArray(n)
pp = IntArray(n)
count = IntArray(n)
var task: Int = 0
while ({task = taskId!!.getAndIncrement(); task}() < NTASKS) {
runTask(task)
}
}
companion object {
private val NCHUNKS = 150
private var CHUNKSZ: Int = 0
private var NTASKS: Int = 0
private var n: Int = 0
private var Fact: IntArray? = null
private var maxFlips: IntArray? = null
private var chkSums: IntArray? = null
private var taskId: AtomicInteger? = null
internal fun printResult(n: Int, res: Int, chk: Int) {
println(chk.toString() + "\nPfannkuchen(" + n + ") = " + res)
}
@JvmStatic
fun main(args: Array<String>) {
n = if (args.isNotEmpty()) Integer.parseInt(args[0]) else 12
if (n < 0 || n > 12) { // 13! won't fit into int
printResult(n, -1, -1)
return
}
if (n <= 1) {
printResult(n, 0, 0)
return
}
Fact = IntArray(n + 1)
Fact!![0] = 1
for (i in 1..Fact!!.size - 1) {
Fact!![i] = Fact!![i - 1] * i
}
CHUNKSZ = (Fact!![n] + NCHUNKS - 1) / NCHUNKS
NTASKS = (Fact!![n] + CHUNKSZ - 1) / CHUNKSZ
maxFlips = IntArray(NTASKS)
chkSums = IntArray(NTASKS)
taskId = AtomicInteger(0)
val nthreads = 1
val threads = arrayOfNulls<Thread>(nthreads)
for (i in 0..nthreads - 1) {
threads[i] = Thread(fannkuchredux())
threads[i]!!.start()
}
for (t in threads) {
try {
t!!.join()
} catch (e: InterruptedException) {
}
}
var res = 0
for (v in maxFlips!!) {
res = Math.max(res, v)
}
var chk = 0
for (v in chkSums!!) {
chk += v
}
printResult(n, res, chk)
}
}
}
......@@ -69,6 +69,7 @@ onlydirs =
regexdna
binarytrees
chameneosredux
fannkuchredux
......
/*
* The Computer Language Benchmarks Game
* http://benchmarksgame.alioth.debian.org/
*
* Contributed by Oleg Mazurov, June 2010
* configured for just one worker thread
*
*/
import java.util.concurrent.atomic.AtomicInteger;
public final class fannkuchredux implements Runnable
{
private static final int NCHUNKS = 150;
private static int CHUNKSZ;
private static int NTASKS;
private static int n;
private static int[] Fact;
private static int[] maxFlips;
private static int[] chkSums;
private static AtomicInteger taskId;
int[] p, pp, count;
void print()
{
for ( int i = 0; i < p.length; i++ ) {
System.out.print( p[i] + 1 );
}
System.out.println();
}
void firstPermutation( int idx )
{
for ( int i=0; i<p.length; ++i ) {
p[i] = i;
}
for ( int i=count.length-1; i>0; --i ) {
int d = idx / Fact[i];
count[i] = d;
idx = idx % Fact[i];
System.arraycopy( p, 0, pp, 0, i+1 );
for ( int j=0; j<=i; ++j ) {
p[j] = j+d <= i ? pp[j+d] : pp[j+d-i-1];
}
}
}
boolean nextPermutation()
{
int first = p[1];
p[1] = p[0];
p[0] = first;
int i=1;
while ( ++count[i] > i ) {
count[i++] = 0;
int next = p[0] = p[1];
for ( int j=1; j<i; ++j ) {
p[j] = p[j+1];
}
p[i] = first;
first = next;
}
return true;
}
int countFlips()
{
int flips = 1;
int first = p[0];
if ( p[first] != 0 ) {
System.arraycopy( p, 0, pp, 0, pp.length );
do {
++flips;
for ( int lo = 1, hi = first - 1; lo < hi; ++lo, --hi ) {
int t = pp[lo];
pp[lo] = pp[hi];
pp[hi] = t;
}
int t = pp[first];
pp[first] = first;
first = t;
} while ( pp[first] != 0 );
}
return flips;
}
void runTask( int task )
{
int idxMin = task*CHUNKSZ;
int idxMax = Math.min( Fact[n], idxMin+CHUNKSZ );
firstPermutation( idxMin );
int maxflips = 1;
int chksum = 0;
for ( int i=idxMin;; ) {
if ( p[0] != 0 ) {
int flips = countFlips();
maxflips = Math.max( maxflips, flips );
chksum += i%2 ==0 ? flips : -flips;
}
if ( ++i == idxMax ) {
break;
}
nextPermutation();
}
maxFlips[task] = maxflips;
chkSums[task] = chksum;
}
public void run()
{
p = new int[n];
pp = new int[n];
count = new int[n];
int task;
while ( ( task = taskId.getAndIncrement() ) < NTASKS ) {
runTask( task );
}
}
static void printResult( int n, int res, int chk )
{
System.out.println( chk+"\nPfannkuchen("+n+") = "+res );
}
public static void main( String[] args )
{
n = args.length > 0 ? Integer.parseInt( args[0] ) : 12;
if ( n < 0 || n > 12 ) { // 13! won't fit into int
printResult( n, -1, -1 );
return;
}
if ( n <= 1 ) {
printResult( n, 0, 0 );
return;
}
Fact = new int[n+1];
Fact[0] = 1;
for ( int i=1; i<Fact.length; ++i ) {
Fact[i] = Fact[i-1] * i;
}
CHUNKSZ = (Fact[n] + NCHUNKS - 1) / NCHUNKS;
NTASKS = (Fact[n] + CHUNKSZ - 1) / CHUNKSZ;
maxFlips = new int[NTASKS];
chkSums = new int[NTASKS];
taskId = new AtomicInteger(0);
int nthreads = 1;
Thread[] threads = new Thread[nthreads];
for ( int i=0; i<nthreads; ++i ) {
threads[i] = new Thread( new fannkuchredux() );
threads[i].start();
}
for ( Thread t : threads ) {
try {
t.join();
}
catch ( InterruptedException e ) {}
}
int res = 0;
for ( int v : maxFlips ) {
res = Math.max( res, v );
}
int chk = 0;
for ( int v : chkSums ) {
chk += v;
}
printResult( n, res, chk );
}
}
/*
* The Computer Language Benchmarks Game
* http://benchmarksgame.alioth.debian.org/
*
* Based on Java version (#3 by Oleg Mazurov
* Contributed by Hank Grabowski
*
*/
import java.util.concurrent.atomic.AtomicInteger
class fannkuchredux : Runnable {
internal var p: IntArray = IntArray(0)
internal var pp: IntArray = IntArray(0)
internal var count: IntArray = IntArray(0)
internal fun print() {
for (i in p.indices) {
print(p[i] + 1)
}
println()
}
internal fun firstPermutation(idx: Int) {
var idx = idx
for (i in p.indices) {
p[i] = i
}
for (i in count.size - 1 downTo 1) {
val d = idx / Fact!![i]
count[i] = d
idx = idx % Fact!![i]
System.arraycopy(p, 0, pp, 0, i + 1)
for (j in 0..i) {
p[j] = if (j + d <= i) pp[j + d] else pp[j + d - i - 1]
}
}
}
internal fun nextPermutation(): Boolean {
var first = p[1]
p[1] = p[0]
p[0] = first
var i = 1
while (++count[i] > i) {
count[i++] = 0
p[0] = p[1]
val next = p[0]
for (j in 1..i - 1) {
p[j] = p[j + 1]
}
p[i] = first
first = next
}
return true
}
internal fun countFlips(): Int {
var flips = 1
var first = p[0]
if (p[first] != 0) {
System.arraycopy(p, 0, pp, 0, pp.size)
do {
++flips
var lo = 1
var hi = first - 1
while (lo < hi) {
val t = pp[lo]
pp[lo] = pp[hi]
pp[hi] = t
++lo
--hi
}
val t = pp[first]
pp[first] = first
first = t
} while (pp[first] != 0)
}
return flips
}
internal fun runTask(task: Int) {
val idxMin = task * CHUNKSZ
val idxMax = Math.min(Fact!![n], idxMin + CHUNKSZ)
firstPermutation(idxMin)
var maxflips = 1
var chksum = 0
var i = idxMin
while (true) {
if (p[0] != 0) {
val flips = countFlips()
maxflips = Math.max(maxflips, flips)
chksum += if (i % 2 == 0) flips else -flips
}
if (++i == idxMax) {
break
}
nextPermutation()
}
maxFlips!![task] = maxflips
chkSums!![task] = chksum
}
override fun run() {
p = IntArray(n)
pp = IntArray(n)
count = IntArray(n)
var task: Int = 0
while ({task = taskId!!.getAndIncrement(); task}() < NTASKS) {
runTask(task)
}
}
companion object {
private val NCHUNKS = 150
private var CHUNKSZ: Int = 0
private var NTASKS: Int = 0
private var n: Int = 0
private var Fact: IntArray? = null
private var maxFlips: IntArray? = null
private var chkSums: IntArray? = null
private var taskId: AtomicInteger? = null
internal fun printResult(n: Int, res: Int, chk: Int) {
println(chk.toString() + "\nPfannkuchen(" + n + ") = " + res)
}
@JvmStatic
fun main(args: Array<String>) {
n = if (args.isNotEmpty()) Integer.parseInt(args[0]) else 12
if (n < 0 || n > 12) { // 13! won't fit into int
printResult(n, -1, -1)
return
}
if (n <= 1) {
printResult(n, 0, 0)
return
}
Fact = IntArray(n + 1)
Fact!![0] = 1
for (i in 1..Fact!!.size - 1) {
Fact!![i] = Fact!![i - 1] * i
}
CHUNKSZ = (Fact!![n] + NCHUNKS - 1) / NCHUNKS
NTASKS = (Fact!![n] + CHUNKSZ - 1) / CHUNKSZ
maxFlips = IntArray(NTASKS)
chkSums = IntArray(NTASKS)
taskId = AtomicInteger(0)
val nthreads = 1
val threads = arrayOfNulls<Thread>(nthreads)
for (i in 0..nthreads - 1) {
threads[i] = Thread(fannkuchredux())
threads[i]!!.start()
}
for (t in threads) {
try {
t!!.join()
} catch (e: InterruptedException) {
}
}
var res = 0
for (v in maxFlips!!) {
res = Math.max(res, v)
}
var chk = 0
for (v in chkSums!!) {
chk += v
}
printResult(n, res, chk)
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment