Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-4041-

Improving my answer to Euler #4

Name: Sam 2010-05-17 5:57

//The sollution to Project Euler Problem 4
//By Sam

#include <iostream>
#include <math.h>

int reverse(int);
int digitCount(int);
bool palindrome(int);

int main(){

    /* Lazy block comments ;)
    int test;
    while(true){
        std::cout << "Test if palindromic: ";
        std::cin >> test;
        if(palindrome(test))
            std::cout << "This is a palindrome.";
        else
            std::cout << "This is not a palindrome.";
        std::cout << std::endl;
    }
    //*/
   
    int result=0;
    int second=0;
    int highest=0;
    //Loop through all possible numbers that we can times together
    for(int first = 999;first > 100;first--){
        for(second = first;second > 100; second--){
           
            //Find the result
            result = first * second;
            //Record the highest one we get
            if(palindrome(result) && result > highest)
                highest = result;
        }

    }

    std::cout << "The largest palindrome made from the product of two 3-digit numbers is " << highest;

    return 0;
}

bool palindrome(int number){
    //if the number = the reverse number
    return (number == reverse(number));
}

int reverse(int number){
   
    int currentUnit = 0;
    int oppositeUnit = 0;
    int newPosition=0;
    int progressive = 0;
    int finalNumber=0;
    int previous=0;

    //For the program, the number of digits start from an index of 0 hence -1
    int digits = digitCount(number) - 1;

    //Loop through the number backwards
    for(int i = digits;i >= 0;i--){
        //Where the target digit is units wise, and where it should be
        currentUnit = pow(10,i);
        oppositeUnit = pow(10,digits - i);
        //Take crap out from the right
        progressive = floor(number / currentUnit);
        //Take crap out from the left
        newPosition = progressive - (previous * 10);
        //Calculate what we will be taking out next iteration
        previous = progressive;
        //Put isolated number in correct units and add to final number
        finalNumber += newPosition * oppositeUnit;
    }
    return finalNumber;
}

int digitCount(int number){
    //Start the variables, size needs to be larger than 10
    int digits=0;
    float size=10.1;
    //See if dividing by 1, 10, 100.. etc reduces the units of the number
    while(size > 10){
        //If the size is under 10, we know we have hit the end of the number.
        size = number / pow(10,digits);
        digits++;
    }
    return digits;
}

Name: Anonymous 2010-05-17 6:08

learn to use code tags.

also,
combinations :: [[a]] -> [[a]]
combinations [] = [[]]
combinations (xs:xss) = [ x:y | x <- xs, y <- combinations xss ]

main :: IO ()
main = putStrLn . head . filter (ap (==) reverse) . map (show . product) . combinations . replicate 2 $ enumFromThenTo 999 998 1

Name: Anonymous 2010-05-17 6:14

I dont understand that code at all.

Name: Anonymous 2010-05-17 6:16

I've dug out my solution for you


//  pipe output through sort -n

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int ispalindrome(char *s) {
  char *sr,*p,*pr;
  int r;
  sr = strdup(s);
  pr = sr + strlen(s);
  *pr-- = 0;
  for(p=s;*p;p++,pr--)
    *pr = *p;
  r = strcmp(s,sr);
  free(sr);
  return !r;
}

int main() {
  int x,y;
  char s[64];
  for(x=999;x;x--) {
    for(y=999;y;y--) {
      sprintf(s,"%d",x*y);
      if(ispalindrome(s))
        printf("%s\n",s);
    }
  }
  return 0;
}

Name: Sam 2010-05-17 6:20

Im pretty much a c++ noob, your ispalindrome looks a lot freaking better, but I dont understand it for shit.

Name: Anonymous 2010-05-17 6:40

>>3
pairsOfThreeDigitNumbers = combinations [[999,998..1],[999,998..1]]
productsConvertedToStrings = map (show . product)
isPalindrome = ap (==) reverse
main = putStrLn . head . filter isPalindrome $ productsConvertedToStrings pairsOfThreeDigitNumbers

Name: Anonymous 2010-05-17 7:48

>>2,6
main = print . maximum $ [x * y | x <- [999,998..100], y <- [999,998..100], ap (==) reverse . show $ x * y]

Name: Anonymous 2010-05-17 7:59

my python is shorter than your haskell, >>7

print max([ x*y for x in range(100,999) for y in xrange(100,999) if str(x*y) == str(x*y)[::-1] ])

Name: Anonymous 2010-05-17 8:25

>>8
yes, but your python also takes over 8 times as long to run.

Name: Anonymous 2010-05-17 8:52

Go suck a [code]-tagged dick, [b]Sam[/b].

Name: Anonymous 2010-05-17 9:40


# lol ruby
puts Array.new(899){|i|Array.new(899){|j|(j+100)*(i+100)}.select{|s|s.to_s==s.to_s.reverse}.sort.last||0}.sort.last

Name: Anonymous 2010-05-17 10:11

/r/equesting erlang version which spwans 899*899 processes, where each process checks that x*y == reverse(x*y).

That'll be real enterprise scalable solution!

Name: Anonymous 2010-05-17 16:52

Here's an inefficient(lazy string conversion) CL solution:

(defun palindromep (x)
  (let ((s (format nil "~D" x)))
    (equal (reverse s) s)))

(defun find-palindrome-in-range (x y) 
  (loop for i from x downto y do
        (loop for j from x downto y
              do (let ((a (* i j)))
                   (when (palindromep a)            
                     (return-from find-palindrome-in-range a))))))

(find-palindrome-in-range 999 100) ;=>580085

Name: Anonymous 2010-05-18 5:28

>>2,6,7
Useless code.
main=print.maximum$[read$p::Int|let l=[100..999],x<-l,y<-l,let p=show$x*y,p==(reverse p)]
(0.96 secs, 229631760 bytes)

Name: >>13 2010-05-18 6:21

CL-USER> (time (find-palindrome-in-range 999 100))
Evaluation took:
  0.016 seconds of real time
  0.015625 seconds of total run time (0.015625 user, 0.000000 system)
  100.00% CPU
  27,368,892 processor cycles
  1,897,600 bytes consed

Name: >>14 2010-05-18 6:28

But the answer is wrong.

Name: Anonymous 2010-05-18 7:22

>>16
Oh damn, you're right!
Here's the fixed version:

(defun palindromep (x)
  (let ((s (format nil "~D" x)))
    (equal (reverse s) s)))

(require :iterate) (use-package :iterate)

(defun find-palindrome-in-range (x y)
  (iter (for i from y downto x)
        (maximizing    
          (iter (for j from i downto x)
                (finding (* i j) such-that #'palindromep on-failure 0)))))

Name: Anonymous 2010-05-18 7:26

And profiling/timing information:

CL-USER> (time (find-palindrome-in-range 100 999))
Evaluation took:
  0.454 seconds of real time
  0.453125 seconds of total run time (0.453125 user, 0.000000 system)
  [ Run times consist of 0.048 seconds GC time, and 0.406 seconds non-GC time. ]
  99.78% CPU
  1,081,934,397 processor cycles
  137,371,272 bytes consed
 
906609
CL-USER> (find-palindrome-in-range 100 999)
measuring PROFILE overhead..done
  seconds  |    consed   |  calls  |  sec/call  |  name 
-----------------------------------------------------------
     0.514 | 144,385,488 | 292,347 |   0.000002 | PALINDROMEP
     0.084 |           0 |       1 |   0.083722 | FIND-PALINDROME-IN-RANGE
-----------------------------------------------------------
     0.598 | 144,385,488 | 292,348 |            | Total

estimated total profiling overhead: 0.25 seconds
overhead estimation parameters:
  3.2000003e-8s/call, 8.42e-7s total profiling, 4.34e-7s internal profiling
906609



Looks like I'll need to write a non-naive palindromep if i want to improve those timings.

Name: Anonymous 2010-05-18 8:30

U MENA HASKAL

$ghc -O2 -o euler4 euler4.hs
$./euler4 +RTS -t -RTS
./euler4 +RTS -t
906609
<<ghc: 203850828 bytes, 389 GCs, 27464/27464 avg/max bytes residency (1 samples), 1M in use, 0.00 INIT (0.00 elapsed), 0.16 MUT (0.16 elapsed), 0.00 GC (0.01 elapsed) :ghc>>

;;;lol scheme

(define (palindrome? num)
  (let ((num (string->list (number->string num))))
  (equal? num (reverse num))))
 
(define (find-palindromes from to)
  (letrec ((rec
            (lambda (x y lst)
              (cond ((= x to)
                     (reverse lst))
                    ((= y to)
                     (rec (+ x 1) from lst))
                    ((palindrome? (* x y))
                     (rec x (+ y 1) (cons (* x y) lst)))
                    (else
                     (rec x (+ y 1) lst))))))
    (rec from from '())))
 
(time (apply max (find-palindromes 111 999)))
=>cpu time: 1227 real time: 1252 gc time: 74
906609

Name: Anonymous 2010-05-18 12:24

>>19
Writing a primitive recursion is unnecessary and only turns people off scheme.

(import (srfi :13) (srfi :42))
(define (palindrome? number)
  (let ((numstring (number->string number)))
    (string=? numstring (string-reverse numstring))))
(define (find-palindromes to from)
  (list-ec (:range i to from)
           (:range j to from)
           (:let n (* i j))
           (if (palindrome? n))
           n))
(time (apply max (find-palindromes 100 1000)))
running stats for (apply max (find-palindromes 100 1000)):
    67 collections
    936 ms elapsed cpu time, including 89 ms collecting
    986 ms elapsed real time, including 98 ms collecting
    278422240 bytes allocated
906609

Name: Anonymous 2010-05-18 12:41

Why do you use strings? what dumbasses.


         (defun reverse-integer (integer)
       "Reverse a non-zero positive integer"
       (do ((i (floor (log integer 10)) (1- i))
        (sum 0 (+ sum (* (rem integer 10)
                 (expt 10 i))))
        (integer integer (floor (/ integer 10))))
           ((zerop i) (+ sum integer))))

         (defun palindrome-p (x)
       (= x (reverse-integer x)))

Name: Anonymous 2010-05-18 12:50

Comprehensions and String Libraries.
What's the point then? Might as well implement Haskell.

Name: >>17 2010-05-18 12:57

>>21
Your integer version is actually slower than the string version:

;;; Integer version from >>21
CL-USER> (time (find-palindrome-in-range 100 999))
Evaluation took:
  0.610 seconds of real time
  0.609375 seconds of total run time (0.609375 user, 0.000000 system)
  99.84% CPU
  1,461,927,303 processor cycles
  94,789,536 bytes consed
 
STYLE-WARNING: redefining PALINDROMEP in DEFUN
906609
;;; String version from >>17
CL-USER> (time (find-palindrome-in-range 100 999))
Evaluation took:
  0.484 seconds of real time
  0.484375 seconds of total run time (0.484375 user, 0.000000 system)
  [ Run times consist of 0.031 seconds GC time, and 0.454 seconds non-GC time. ]
  100.00% CPU
  1,150,893,090 processor cycles
  137,372,928 bytes consed
 
906609


I actually expected the integer version to be faster, but it doesn't seem to be. I think the reason why your version is slower is that you use floor/log, while using truncate or mod would likely be better choices, and maybe some declarations too.

Name: Anonymous 2010-05-18 13:00

>>22
What's the point?
Legibility. The string library is a bit generous, since I only used string-reverse.There is a time and a place for writing out your recursions by hand, but a comprehension isn't one of them. It's a pattern you are going to use over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over. If you are not using the abstraction facilities that Scheme gives you, then why bother using Scheme at all? If you want to be a caveman, code in Assembly.

While I'm moaning, If you write out a recursion by hand where map, filter, fold[lr], for-each or unfold could be used, you are a fucking retard and should get the fuck out of here

Name: >>17 2010-05-18 13:05

>>24
He's using CL, not Scheme, but the point does apply. He should aim for elegant code and only optimize when needed. After he profiles his code and sees that something is the bottleneck, only then he can write more butchered code for the sake of speed. (To be fair, palindromep function is the bottleneck, and he was right to try writing a more efficient version, but too bad his version is actually SLOWER than the string one because he used too costly function calls).

Name: >>25 2010-05-18 13:07

Nevermind that, I thought you were replying to >>21, not >>22, altough the point still applies.

Name: Anonymous 2010-05-18 13:11

>>23
You're a fucking idiot. The real reason my version is slower than your version is because you're comparing an implementation-quality function with the plain algorithm. fucking dumbass CL programmers came out of a university with no real experience and they don't get shit, talk shit and code shit. eat a fucking dick

Name: Anonymous 2010-05-18 13:11

>>26
damn should have refreshed.

Name: Anonymous 2010-05-18 13:17

>>28
Neither function was optimized, so it was only fair.

Name: Erlang variant finished 2010-05-18 13:20

Yay. Behold ENTERPRISE SCALABLE solution.

-module(tut).
-export([start/0, is_palindrome/3, receiver/2 ]).


is_palindrome(X, Y, Pid) ->
    M1 = integer_to_list(X * Y),
    M2 = lists:reverse(M1),
    if
        M1 == M2 ->
            Pid ! {X * Y, true};
        M1 /= M2->
            Pid ! false
    end.

receiver(0, List) ->
    M = lists:max(List),
    io:format("RESULT: ~p~n", [M]),
    halt();
receiver(N, List) ->
    receive
        {X, true} ->
            receiver(N-1, [X|List]);
        false ->
            receiver(N-1, List)
    end.



spawn_processes(N, Nmax, Receiver_PID) ->
    if
        N + 1 =< Nmax ->
            spawn(tut, is_palindrome, [N div 1000, N rem 1000, Receiver_PID]),
            spawn_processes(N+1, Nmax, Receiver_PID);
        N + 1 >= Nmax ->
            {completed, Nmax}           
    end
    .

start() ->
    START=100000,
    N=900000,
    Receiver_PID = spawn(tut, receiver, [N,[]]),
    spawn_processes(START,START+N, Receiver_PID).





$ time erl -run tut
Erlang R13B03 (erts-5.7.4) [source] [64-bit] [smp:4:4] [rq:4] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.7.4  (abort with ^G)
1> RESULT: 906609

real    0m6.177s
user    0m10.240s
sys    0m3.790s


it even runs in reasonable amount of time. Take that, java threads!

Name: >>19 2010-05-18 13:43

>>27
That was indeed the case.
I still enjoy me a (letrec ...) and a (lambda ...) or two.
Readability is paramount if you ever intend your code to be used elsewhere and understood by somebody else, I agree. And abstraction is very useful, but I feel for this particular case, the extra libraries are overkill.

Name: Anonymous 2010-05-18 14:48

>>30
You don't get it do you fucking idiot? I was right you don't get it. FORMAT is optimized you fucking moron. REVERSE is optimized you fucking dumford. Fucking stupid dumb piece of shit. God damn fucking atheist sonscumbitchassnigfaggot

Name: Anonymous 2010-05-18 15:36

>>33
back to /b/, please.

Name: Anonymous 2010-05-18 15:45

>>33
And the functions you used aren't optimized? If your function was written for efficiency, it would have been fast. And format isn't always optimized (sometimes it may be, using a compiler transform). If I wanted zomgspeed, I would have used formatter wrapped around the function in a closure, and declared the arguments' type. Your code benefited from the same optimizations as my code. Your code was slow because of the choice of functions.

Name: 17 2010-05-18 16:04

Hah, obtaining good performance is easy even if you cons up a list, much better than strings at that:

(defun integer-to-list (x &optional (base 10))
  (labels ((rec (i res)
             (if (zerop i) res        
                  (multiple-value-bind (div mod)
                      (truncate i base)
                    (rec div (cons mod res))))))
    (rec x nil)))

(defun palindromep (x)
  (let ((list (integer-to-list x)))
    (equal list (reverse list))))

Name: Anonymous 2010-05-18 16:04

And the benchmark:

CL-USER> (time (find-palindrome-in-range 100 999))
Evaluation took:
  0.062 seconds of real time
  0.062500 seconds of total run time (0.062500 user, 0.000000 system)
  100.00% CPU
  177,844,266 processor cycles
  27,449,040 bytes consed

Name: Anonymous 2010-05-18 17:20

>>35
What a fucking idiot. I wrote the algorithm. You didn't write any algorithm, you only mix-matched the opt functions. Now shut the up fuck.

Name: Anonymous 2010-05-18 17:34

>>28,33,38
'thinks he's a hotshot for making an elementary algorithm which reverses the order of digits of a base 10 number.
'thinks said poster didn't know the complexity classes of the algos involved, including his current CL implementation's


I can smell the butthurt and delicious tears from miles away...

Sorry, I couldn't abstain, but this has been keeping me laughing for a while.

/me returns back to /b/ for making a /b/-quality post

Name: Anonymous 2010-05-18 19:00

>>19,36-37
import Control.Monad
import Control.Monad.Instances

main = print $ maximum [p :: Int | x <- [101..999], y <- dropWhile ((< x) . join (*)) [
101..x], let p = x * y, ap (==) reverse $ show p]

build with ghc -O -fvia-c -optc -O2 -optc -march=native -optc -mtune=native --make euler4.hs and run:
euler4 +RTS -t
906609
<<ghc: 95275052 bytes, 182 GCs, 3388/3388 avg/max bytes residency (1 samples), 1M in use, 0.00 INIT (0.00 elapsed), 0.08 MUT (0.11 elapsed), 0.00 GC (0.00 elapsed) :ghc>>

Name: Anonymous 2010-05-18 19:06

Haha, oh wow. My SEPPLES solution was retarded.

int Projects::EulerProject4() {
    /*
        A palindromic number reads the same both ways.
        The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.

        Find the largest palindrome made from the product of two 3-digit numbers.
    */
    int palindrome = 0;
    const int LOOP_MAX = 999;

    for (int loopiter1 = 100; loopiter1 < LOOP_MAX; loopiter1++) {
        for (int loopiter2 = 100; loopiter2 < LOOP_MAX; loopiter2++) {
            int result = loopiter1 * loopiter2;
            int grumblyface = result;
            char len = (result > 99999) ? 6 : 5;
            bool flag = true;
            int* grumblyarray = new int[len];
            for (char b = 0; b < len; b++) {
                int digit = grumblyface % 10;
                grumblyface /= 10;
                grumblyarray[b] = digit;
            }
            for (int i = 0; i < (len / 2); i++) {
                if (grumblyarray[i] != grumblyarray[(len - 1) - i]) {
                    flag = false;
                    break;
                }
            }
            if (flag) {
                palindrome = result;
            }
            delete grumblyarray;
        }
    }
    return palindrome;
}

Name: Anonymous 2010-05-18 19:13

>>39
'fails at greentext when facing aphostrophes. still thinks he[code]'s a cool guy.

Name: Anonymous 2010-05-18 19:52

>>42
BBCoed fail > missing apostrophe.

Name: Anonymous 2010-05-18 21:37

'implying that there's a valid way to make apostrophes work while in greentext
`implying that using an accent grave isn't the better solution overall

Name: Anonymous 2010-05-19 2:34

>>44
It's not an accent if it isn't combined with another glyph. It's just a backtick.
Your solution breaks on ``proper quotes'', though.

Name: Anonymous 2010-05-19 3:00

>>45
`it works just fine with your ``faggot quotes".

Name: Anonymous 2010-05-19 4:29

>>46
Another victory for ``proper quotes''!

Name: Anonymous 2010-11-26 16:09

Don't change these.
Name: Email:
Entire Thread Thread List