Talk:Kaprekar numbers

Revision as of 07:45, 8 October 2012 by rosettacode>Lhignight (→‎Conflict Resolution?: Compilation testing of Common Lisp versions)

We've been linked to from a prestigious source

The On-Line Encyclopedia of Integer Sequences has a link to this RC page! (The link is to the google cache - for the highlight) --Paddy3118 22:24, 29 August 2011 (UTC)

And on this entry A194218 we get mentioned a second time as a place to compare programs! This is just brilliant to me as I have admired OEIS for what it collates for some time. --Paddy3118 06:11, 30 August 2011 (UTC)

Sweet. --Michael Mol 13:15, 30 August 2011 (UTC)

Java count missing

Just add (and show), the count of how many there are <1million and you will have completed the stretch goal! --Paddy3118 14:07, 7 June 2011 (UTC)

I had actually added it as a test because I saw the other examples do it, but for some reason I didn't read it as a requirement so I took it out. Mornings are hard. --Mwn3d 14:47, 7 June 2011 (UTC)
:-)
--Paddy3118 17:29, 7 June 2011 (UTC)

Why the complexity?

The wikipedia page says "Let X be a non-negative integer. X is a Kaprekar number for base b if there exist non-negative integers n, A, and positive number B satisfying ...". In other words A can be zero. Why do we have to have a bunch of text claiming that A cannot be zero but A can be an empty string and that it is meaningful to add an empty string to a number? (Can't we just take advantage of the fact that leading zero digits do not change the value of a number?) --Rdm 20:56, 7 June 2011 (UTC)

To me the text "However a conceptual single split at the very end or before the first digit that produces one empty string does have the empty string counted" means that A can be zero. Unless I'm confused about what A and B are. --Mwn3d 22:30, 7 June 2011 (UTC)

Consider 100*100 = 10000 which could be split as 100 + 00. Now the 00 is disallowed. Compare that with 1*1 = 1 which is a K-number. For this to be a k-number then it must be expressed as either 1 plus no digists to the right or no digits to the left + 1. Either way no digits is treated as a positive integer of value zero but any string of one or more noughts is expressly forbidden.

Having 1 in the series seemed to add that complexity that needed explaining in my mind. --Paddy3118 23:14, 7 June 2011 (UTC)

It has to do with the way that the splitting is done mathematically, i.e.,   and   where  ; in the case of  , it becomes possible to use  . This only works for that value; nothing larger is equal to itself when squared and zero is inadmissible by the constraint on  . Trust a mathematician to fluff the operation of splitting a number-string and introduce an unwanted special case! –Donal Fellows 23:48, 7 June 2011 (UTC)
I was reading the expressions, but the implication just fazed me. I had a mental block about the 1 case, even when it was explained more explicitely. Gosh, I'm not getting senile? er, I'll change that ? to ! --Paddy3118 09:05, 8 June 2011 (UTC)

Which sounds better?

What should we say, "split into parts" or "split once into whole number components made of groups of neighbouring digits from within the number"?

We are splitting into the number into numeric values the belong to the set of "whole numbers" aren't we? Or is there a misunderstanding here?

"split into parts" sounds too vague to me.

--Markhobley 16:06, 8 June 2011 (UTC)

If I had to change it from what we have now I'd say "split into two parts". The way it is now seems fine to me especially with the examples in the description. Since the number is specified as an integer, I don't think we need to add "whole number" noise. --Mwn3d 16:16, 8 June 2011 (UTC)
Right. The "whole numbers" verbage avoids the issue of explaining that chains of zeros do not fulfil the criteria, (although we would probably still need to keep that as a note to remind the task implementers.) --Markhobley 16:22, 8 June 2011 (UTC)
"Whole numbers", to me, includes 0 so I don't think that works that way. Is "whole numbers" an official mathematical set like "natural numbers"? Maybe say "split in to two positive parts"? --Mwn3d 16:33, 8 June 2011 (UTC)
There isn't a consensus on the definition of a whole number, natural numbers, or counting number (especially in grammer/grade/highschool/secondary school texts). See the links for "Mathworld" http://mathworld.wolfram.com/WholeNumber.html, http://mathworld.wolfram.com/NaturalNumber.html, http://mathworld.wolfram.com/CountingNumber.html, all those seem to prefer defintions based on integers (positive integers, nonnegative integers, negative intergers, ∙∙∙ --Gerard Schildberger 19:26, 21 March 2012 (UTC)
Generally zero is not considered to be a whole number, but there are people who would disagree. We could use the term "integers greater than or equal to one" --Markhobley 19:40, 8 June 2011 (UTC)
FWIW zero is positive, but not a whole number, so "positive parts" would be no clearer IMHO, I would also call them numerical components, rather than parts, because 12 can be split into parts of sizes 8 and 4, but 1 and 2 are its numerical components. --Markhobley 19:45, 8 June 2011 (UTC)
OK 0 cannot be positive because then no one would need to call anything "non-negative" ([1] [2] [3]). The phrase "string representation" earlier in the first sentence avoids the "split" definition you're thinking of. And once again, the examples following the language reinforce the wording. --Mwn3d 19:58, 8 June 2011 (UTC)

Promoting to full task status

As the resolution of any of the discussions above in unlikely to change the fundamental task goals, and we have several correct examples.--Paddy3118 20:07, 8 June 2011 (UTC)

I say yes. Go! --Markhobley 20:11, 8 June 2011 (UTC)

C++ sample code

I'm tempted to change all the "long" type to "long long" in the C++ sample code, because it would fail on 32 bit system as is. --Ledrug 17:08, 14 June 2011 (UTC)

That change seems fine since the output goes up pretty high anyway. Does that just mean they used a 64-bit machine? --Mwn3d 17:17, 14 June 2011 (UTC)
What 'long' means depends on the compiler, but it's typically defined to be the longest native integer type, while 'long long' is (I think) defined to be 64-bit. Someone correct me if I'm wrong. I'll change the code anyhow, because it overflows with 32 bit long for sure. --Ledrug 17:25, 14 June 2011 (UTC)
On every C and C++ compiler I've used on a 64-bit OS (so, GNU on Linux and MSVC/MSVC++ on Windows), 'long' is 32-bits. 'long long' is 64-bits. I don't know about, e.g. SPARC64, though. That's why you get things like uint32_t from stdint.h or DWORD from Windows.h. --Michael Mol 18:05, 14 June 2011 (UTC)
It's always sort of confusing to me anyway. For reference, see http://www.unix.org/whitepapers/64bit.html, which also has a table for integer types. It's true that if you worry about the exact length, use exactly defined types instead of the compiler native ones. --Ledrug 18:28, 14 June 2011 (UTC)
If 53 bits is enough (and I think it is, here), you might also consider using double. --Rdm 20:01, 14 June 2011 (UTC)
Heh, tried double, seg faulted. I'm not very motivated to see what's happening--probably that atol()--so I'll just leave it as is. --Ledrug 21:44, 14 June 2011 (UTC)

What's up with the people modifying the C++ code, previously (before long to long long) it returned wrong numbers, now it simply never returns on 32 bit system with g++ 4.5. Also maybe we should promote testing sample code with full warnings on: g++ gives signedness mismatch warning on line 20. --Ledrug 23:02, 15 June 2011 (UTC)

Would someone modify the code to work for a happy medium and then state on the task page that the C++ code is fragile w.r.t 32/64 bit systems and where the fragility lies? It sounds like it is an issue that should be taken into account when comparing that particular C++ code with other languages.

Come to think of it, maybe other similar languages might state why they don't have an issue? Or maybe there is a separate task here: "Do something that is otherwise straight-forward but needs slightly different code, or will not work on both 32 and 64 bit X86 systems and/or up-to-date, widely used, but different versions of compilers/interpreters"? --Paddy3118 05:06, 16 June 2011 (UTC)

I really don't think it's a language or compiler problem, though. And this task is already pretty straightforward: you take a number and look at its digits, that's it, the language certainly can handle that. --Ledrug 08:54, 16 June 2011 (UTC)

Indentation...

Can we please don't adjust someone else's code indentation just because it's different from yours... --Ledrug 20:21, 14 June 2011 (UTC)

I appreciate that it can be annoying when people touch your code, but it's a wiki. You're going to have to get used to it. My code is changed regularly. Sometimes for the better. Sometimes it's simply changed but not really improved, in my opinion. Unless you want to get involved in edit wars all the time, you're going to have to relax about it. In your case, I honestly thought that the huge indent was accidental. Otherwise I would have left it alone. Fwend 21:23, 14 June 2011 (UTC)
K&R 8 space tab is typical BSD style, I'm not sure why you'd think it's accidental. And I didn't mind someone changine my code, but changing purely because of the code indentation is prone to start an edit war, please don't get too used to it (and I didn't revert your edit, did I?). --Ledrug 21:32, 14 June 2011 (UTC)
You might try leaving the original indentation if it is consistent and "reasonable"; and adjusting to the existing style when making small edits, (helps with the diffs). If you make a large change then probably relax the rules about changing styles? --Paddy3118 04:21, 15 June 2011 (UTC)

All that being said, there's a balance to be struck here between demonstrating that an idiosyncratic style is acceptable vs demonstrating "normal" code for the culture in question. And in this case, it's true that Perl culture is quite accepting of idiosyncracies, but also that the culture as a whole tends toward 4-space indent, not 8. In fact, 4-space indent is specifically recommended in the Camel book. So a good case can be made for either, and people should not get too hung up about either idiosyncratic tabbing or having that idiosyncratic tabbing normalized to something closer to the norm. Certainly for the Perl 6 examples I reserve the right to be a bit pickier about setting the cultural norm, since many new people will be learning Perl 6 by studying these examples, whereas Perl 5 already has large collections of existing code outside of RC. TimToady 06:03, 16 June 2011 (UTC)--

Oh dear, didn't expect this to get the attention of Larry. Let me clarify: it's not because someone changed my indentation; rather since people tend to have very strong opinions about what a tab size is, changing anybody's code just to make the indenting fit one's own taste may start flame wars (well, sort of like what we have now), and people should refrain from doing that IMO. --Ledrug 07:07, 16 June 2011 (UTC)
This isn't really a flamewar, just a back-and-forth defense and clarification of different positions. It's actually pretty normal and healthy for RC. It's when the participants stop arguing in good faith (which I don't see anyone here having done) that it gets bad. --Michael Mol 15:53, 16 June 2011 (UTC)

Old D version

(Regarding the changes to the second D version, that Fwend has reverted: the current second D version returns 0/1 but the function has to return a bool, and D is not C. The C-style code was faster, and it was shorter too. Pre-conditions are a good habit in D, that makes the code safer and less wild-west-style as C code. This C-derived code is also able to accept a bigger range of input n values. And the code has a main too, so it's not just a nonworking fragment.) --Unsigned, added by 95.235.203.130

An answer to a question: it's not n*n that causes the first overflow, it's tens*=10. I think assert(n<=3_162_277_660UL) is correct.
Ah ok, I think I asked that question about overflow. Truth be told, I was only guessing, since I don't even know what a "ulong" is in D. --Ledrug 17:10, 16 June 2011 (UTC)
I think my code should stand, because it shows a different approach to solving the problem, which makes the task page more interesting. Fwend 20:33, 16 June 2011 (UTC)
Multiple approaches are allowed (and encouraged). If the examples do things differently, put them both up and notate them. --Mwn3d 20:41, 16 June 2011 (UTC)
The C version is basically the same as the second and third D versions, slight difference is that it breaks from testing if the first half of nn is already larger than n, so only needs to do half the math for most cases. The goofy looking comparison itself is just coincidence after looking at the quotient/remainder equation. --Ledrug 21:30, 16 June 2011 (UTC)
O, hey that gives me an idea: if (b > n) break; :) Fwend 22:32, 16 June 2011 (UTC)

Extra extra credit?

I just had an idea, maybe make an optional task for code to allow bases other than 10--would that be fun? --Ledrug 22:55, 16 June 2011 (UTC)

Sounds good. Go ahead and add it to the extra credit requirements. I think a reasonable amount of languages should be able to do it easily. --Mwn3d 00:02, 17 June 2011 (UTC)
Added. Now thinking of it, it may be a little hard for most examples using string based methods. Oh well. --Ledrug 00:46, 17 June 2011 (UTC)
I think I already have it for Java. Here's my full base 17 list (I have 24):
1	1	1	0 + 1
16	g	f1	f + 1
64	3d	e2g	e + 2g
225	d4	a52g	a5 + 2g
288	gg	gf01	gf + 01
1536	556	1b43b2	1b4 + 3b2
3377	bbb	8093b2	809 + 3b2
4912	ggg	ggf001	ggf + 001
7425	18bd	24e166g	24e + 166g
9280	1f1f	39b1b94	39b + 1b94
16705	36db	b992c42	b99 + 2c42
20736	43cd	10de32fg	10de + 32fg
30016	61eb	23593f92	2359 + 3f92
36801	785d	351e433g	351e + 433g
37440	7a96	37144382	3714 + 4382
46081	967b	52g94382	52g9 + 4382
46720	98b4	5575433g	5575 + 433g
53505	af26	6ga43f92	6ga4 + 3f92
62785	cd44	9a5532fg	9a55 + 32fg
66816	da36	aeg42c42	aeg4 + 2c42
74241	f1f2	d75f1b94	d75f + 1b94
76096	f854	e1f5166g	e1f5 + 166g
83520	gggg	gggf0001	gggf + 0001
266224	33334	a2c52a07g	a2c5 + 2a07g
--Mwn3d 01:23, 17 June 2011 (UTC)
Great, that looks identical to mine (except I cheated and didn't split 1, because it's not really the same as the rest). --Ledrug 01:42, 17 June 2011 (UTC)
Note that many details of that line format were listed as "for example". Now that we have examples, perhaps that sentence should be removed as superfluous? Or does someone want to promote them to extra credit work? --Rdm 11:15, 27 June 2011 (UTC)

Incomplete output

The task specifically asks that output be shown for n<10000 so when shortening output to fit the page, please ensure that these are still all shown, thanks. --Paddy3118 07:28, 22 June 2011 (UTC)

In base B <> 10

Just an idea : why bother printing in base B ? Being Kaprekar in base B is unrelated to the printing base. Then, when implementing with a loop doing divisions/multiplications by 10, just replace 10 by B to get Kaprekar numbers in base B. Toucan 17:18, 26 June 2011 (UTC)

I don't quite understand that. Can you show an example? --Mwn3d 17:29, 26 June 2011 (UTC)
Let's take an example from the implementation in C:
74241 is a Kaprekar number in base 17. But, written in base 17, it's f1f2, or if you prefer f1f2_17 = 74241_10, with obvious notation.
The fact that it's a Kaprekar number will be better showed when printing in base 17 (numbers with _17 appended), and you will write
f1f2_17^2 = d75f1b94_ 17 and d75f_17 + 1b94_17 = f1f2_17
However, the number is still f1f2_17 = 74241_10 = 12201_16 = ... You can print this number in any base you wish, it's the same number.
As Ledrug says, the only reason to print f1f2 is showing how N^2 may be cut to prove it's a Kaprekar number. But it's not really related to
Kaprekar numbers, it's a "printing in base B" subtask.
Toucan 11:09, 27 June 2011 (UTC)
True. I added the non-base10 extra requirement, and the printing part is there to clearly show if a solution decoupled the numerical aspect from a number's string representation. The base 17 was specifically chosen because languages often can handle base conversion up to 16 natively, so 17 may require a hand-rolled string conversion, which can also be interesting while not difficult. Plus, if you print it out in base 17, it's much easier for a human reader to see the correctness of the solution. --Ledrug 21:25, 26 June 2011 (UTC)

Just for fun

For fun I tried reversing the digits in the squared number (e.g. using "5203" as the "squared number" for 55 instead of "3025") to see if there would be any pattern in the new results. There were some overlaps for numbers that were all repeating digits. I didn't see anything notable. I got 17 rakerpak (kaprekar backwards....get it?) each for base 10 and 17. The code isn't notable either (just add a bit to one line to reverse the string representation of the squared number). I thought it would be kinda neat to think about. --Mwn3d 15:16, 8 August 2011 (UTC)


I tried this for ooRexx

Had to change # to n
But get a syntax error for j=100000 since s=1E+10
It works with Numeric Digits 14

--Walterpachl 14:53, 29 June 2012 (UTC)


Common Lisp Implementation

Let me start by saying that I feel the criteria that should be used to modify existing code are the following:

  • Correctness
  • Fulfilling additional tasks / generality
  • Improved readability
  • Use of a programming languages idioms - For example, in CL the use of multiple return values is preferred to say setting multiple global variables.
  • Improved performance
  • (Note: There may be some special situations missing from this list)

Using these criteria, I modified the original CL implementation mainly because I thought that I could improve the readability by using more Lisp language features like multiple return values. In short, I felt like I was reading a C program written in Lisp: The original code isn't 'Lispy'. Later, I made some changes to the basic algorithm that substantially improved the performance (and even later came across the CO9 technique which again substantially improved performance). Because the original version supports additional number bases, I decided to add a separate fast version and retain the older, more general, version. Recently, Nigel Galloway added support for all number bases to the 'fast implementation'. Based on the criteria above, I would normally find this to be an improvement, however, the code again resembles a C implementation written in Lisp (especially with the global bindings of BASE and BASE-1) and the performance has also decreased substantially. My version is able to finish the first 1 million Kaprekar numbers in ~9.1 seconds; The new version finishes in ~124 seconds. Memory usage and garbage collection also increased by an order of magnitude.

Because the new version lacks additional generality beyond the 'slow version', decreases readability and the use of Lisp idioms, and is substantially slower than the previous version, I've decided to revert the changes made by Nigel. I added this talk section to explain my rationale for making the revision. --Larry Hignight 23:40, 18 September 2012 (UTC)

Hi Lhignight, its good to see your criteria - I hope they are in decreasing order of importance for the general task, as optimising for speed can detract from the other concerns if done to excess - especially if a task can be 'adequately' fulfilled without it. Although you could add another implementation that was faster and leave a more idiomatic example alone. --Paddy3118 16:08, 19 September 2012 (UTC)
Fleshing this out a bit more, in terms of the order of importance, I consider correctness to be the most important criteria, performance the least (unless specifically mentioned in the task), and the remaining criteria are about equal in my opinion. In most programming languages, improved readability and use of language idioms are often highly correlated (at least among experienced users of the language). Performance is a nice bonus item, but if it detracts from any of the other criteria, it should be added as a separate task assuming that it is correct and significantly faster: 5% faster, skip it; 5x faster, add it. --Larry Hignight 23:38, 21 September 2012 (UTC)

Hi Larry, what implementation of common lisp are you using? I only replaced a function number of digits, which calculated the number of digits by dividing by 10 until less than 10 with floor (log N / log Base) which is a reasonable way to determine the number of digits in a number. This should be faster unless your implementation has no reasonable log function. Note that BASE and BASE-1 are not variables they are constants. I didn't change the logic. A mute point now as ledrug has done tha task properly.--Nigel Galloway 18:44, 19 September 2012 (UTC)

Hi Nigel, I did the initial testing using CLISP. I've since tested both versions using LispWorks, which improved your times substantially, but it is still noticeably slower. I'll separate out your other points so that you can respond to each comment directly. --Larry Hignight 22:42, 23 September 2012 (UTC)

"I didn't change the logic."
Perhaps you didn't intend to change the logic, but your version fails to identify 9,999,999 and 99,999,999 as Kaprekar numbers whereas mine correctly identifies them, so yes, you did change the logic. --Larry Hignight 22:42, 23 September 2012 (UTC)

"Note that BASE and BASE-1 are not variables they are constants."
While I applaud the additional mathematical insight that you provided, I'm concerned that you don't have very much experience as a Lisp developer and should probably refrain from modifying existing Lisp solutions. For example, the CLHS explicitly states that setq is used with variables "other than a constant variable." In addition to BASE and BASE-1 not being constants, which isn't what you didn't want in the first place, there are a number of other issues:

  • In CL, the standard method for defining a constant is the defconstant form. It is also the convention in CL to name constants with leading and trailing + characters (eg +base+).
  • The unnecessary use of dynamically scoped variables is discouraged. The preferred method for incorporating base would have been to define it as an optional function parameter with a default value of 10.
  • The manner in which you replaced the num-digits macro resulted in code that was less readable. In my version, it was very clear when the number of digits were being calculated because I used an abstraction to separate this calculation from the function. You eliminated a useful abstraction.
  • For some reason, you replaced the let* form with the lh and rh values with a multiple-value-bind form. I really have no idea why you would do this.
  • I'm not sure why you feel that two calls to log followed by floor() and adding 1 would be faster than a loop that runs in theta(log n) time. --Larry Hignight 22:42, 23 September 2012 (UTC)

"A mute point now as ledrug has done tha task properly."
Yeah, it's kind of a shame that someone broke it though. --Larry Hignight 22:42, 23 September 2012 (UTC)

A lot of hot air for somthing that doesn't exist! I did not break the origional solution, I made it solve the task. Obviously in a way that doesn't suit you. In place of personal abuse you might have changed it to suit you and solve the task. Returning it to a version which doesn't solve the task was not helpful. I was going to restore my version and let you change it, but I'll leave it to you to restore and correct if you think it adds anything. I have a much better idea.--Nigel Galloway 10:40, 26 September 2012 (UTC)

YOUR version is not CORRECT. Anyone can view the history, try the examples above, and see this is true. I left untouched a slower version that solved the 'Extra extra credit' task, which you seem to be obsessed with for some reason. Why you would expect anyone to fix an incorrect, slower, less readable, and less lispy version of your software, when better versions already existed, is way beyond me. --Larry Hignight 01:17, 30 September 2012 (UTC)

Now with +SCARY CAPITALS+! I dont't expect anyone to do anything, it was merely a suggestion that you 'put up or shut up'. I modified your solution so that it worked, with sample output provided. If it didn't work for large numbers (ouside the scope of the task) it is probably because your log algorithms are inaccurate. You changed it back to your solution, which doesn't solve the task. Your situation is that ledrug didn't like your solution and has replaced it with his. If you have nothing to put up on the task page then all this is just hot air. None of your comments and insults have indicated that which you wish me to do about your situation. As I said I have a better idea, which I have placed on the task page.--Nigel Galloway 11:38, 1 October 2012 (UTC)

How on earth is something that doesn't work CORRECTLY a better idea! And for the record, Ledrug replaced YOUR version, not mine. --Larry Hignight 08:24, 4 October 2012 (UTC)

Well, joining the fray. First, the message left on my user talk page by one genius:

Please leave this code alone until you can demonstrate an understanding of this problem. Your second attempt at this is an improvement over your first naive attempt, but still not as interesting as this. Maybe I shall seperate the Casting_out_nines from the Kaprecar part: <lang clisp>(let ((kk (* N N))) (do ((B Base (* B Base))) ()(let (( nr (/ (* N (- B N)) (- B 1)))) (if (< 0 nr) (let ((q (floor (- N nr)))) (if (= kk (+ nr (* q B)))</lang> (unsigned, left by User:Nigel Galloway)

I'll make a few comments, but won't discuss it any more after that, since that would be obviously futile.

  1. I don't know what kind of antique lisp machine you have installed in your basement, but your code does not compile on either SBCL or Clisp. Maybe geniuses shan't be bothered by such trifles.
  2. Your code, once made compile with SBCL (change that do (...) () to do (...) (nil), does exactly the samething mathematically: raise a power of a base repeately, until either it splits the square of n with the right sum, or it's too large. Except you are doing it in a convoluted way, using non-integer methods on integers, and ends up with something literally 100 times slower then my edit you reverted (on SBCL that is, I don't know about your antique lisp machine).
  3. You had one good idea of checking congruence, and a whole lot of terrible ones: being thoughtless in dealing with datatypes (pow and log on integers in C++, / and floor in Lisp); being sloppy in performance tuning (your "v.fast" C++ code isn't all that fast); being vengeful (paddy_cnt?); being narcissistic (own name as variable?); being inconsiderate to code readers (what kind of person posts unindented Lisp?); and generally being an all-around dick.
  4. Your sarcasm in the lisp code was neither subtle nor funny. You give British humor a bad name.

You are probably not stupid, but it's safe to say you are not the smartest person on RC, by a long shot. And smart people around here tend to have good manners, unlike you or I. Stop treating yourself like you are the one true genius, and try to do something that's helpful to people instead of showing off, OK? (my guess: probably not. Oh well.) --Ledrug 00:10, 4 October 2012 (UTC)

Well said. He is clearly more interested in being a pompous dick then contributing quality code to RC. --Larry Hignight 08:24, 4 October 2012 (UTC)

Again ledrug why so angry? I didn't revert your edit, it is a good solution, I left it there and reinstated my solution which you deleted, as, indeed, it was you who deleted Larry's solution. There are three approaches to this problem which I have identified:

1) a naive approach which loops over all numbers testing each fully for Kaprekarness (your first solution);
2) a more sophiscated method which still loops over all numbers but implements a filter based on casting out nines which quickly eliminates seven nineths of the numbers (your second solution, thank you for praising my idea);
3) realizing the nature of the uneliminated numbers it is possible to identify the residual sets to which possible Kaprekar numbers belong and generate them (which my solution does).

I therefore asked you not to delete it, and I said please! I asked you to understand the difference before you changed it, which you may. Agian I would say politely, I said please. Again I thank you for your praise for that which you judge to be my good idea, though of course without accepting your magesterium regarding the quality of any of my ideas.

I use Franz Allegro 9, do you want me to pass your comments 'kind of antique lisp machine you have installed in your basement' on to them? Also the version I use is case sensitive, so your use of t and T to disguish when you want t to mean true and T to mean boolean causes my rather advanced lip machine to identify T as an unbound variable, but I just quietly change it without impuning either you, SBCL, or CLisp.

Finally I have no reason to be vengeful to Paddy, I don't even feel vengeful towards you! He asked that the impementation include a count of the Kaprekars as requested in the task description, and I obliged. I named the count after him as my terrible vengence, I don't see it.--Nigel Galloway 12:12, 4 October 2012 (UTC)

Conflict Resolution?

Hi guys, I and probably others have been lurking on this issue that doesn't seem to be getting closer to a solution. I am not a Lisp expert, but would like to see some resolution.

How about a limited debate? Nigel, Ledrug and Larry should continue the debate for no longer than, say next Monday - others can add their opinions too but the idea being to leave behind reasoned areguments why their view should prevail. Come Tuesday others should read the reasoned arguments and make up their own minds with the page updated to fit the best reasoned point. Or Mike Mol could become a benevolent dictator on Tuesday and just state *the* resolution, to be followed by all.

- Or not. If someone has another idea ...? --Paddy3118 13:26, 4 October 2012 (UTC)

Don't worry about my side, I've said what I wanted to say, and am not getting back into it. Though I'm pessimistic about everyone eventually agreeing to a reasonable resolution: I wouldn't have flat out called someone a self-important dick if past experience showed that he could be reasoned with or that he did have a bit of sincerity when exhibiting his knowledge in spelling the word "please". I'd like to be wrong on this, but I won't hold my breath. --Ledrug 05:59, 5 October 2012 (UTC)
I wrote a list of reasons concerning when I think it is appropriate to change existing code and why I changed Nigel's version (his 7/9/2012 submission) to which he responded with "A lot of hot air for somthing that doesn't exist!" ignoring ALL of my points and implying that I should have fixed his version: "I was going to restore my version and let you change it". I feel that the criteria that I previously listed are still valid, and despite what Nigel might claim, there are major issues with his version (in terms of Lisp constructs, idioms and formatting) which is why I removed his version, and not because I was being vengeful, as he stated below. His submission is badly written and should be removed. It is that simple. If Nigel would like to change the version written by Ledrug, I feel that he should write a list of valid reasons which can be debated. If the reasons are sound and agreeable, then he be allowed to modify Ledrug's version with one caveat: All of Nigel's Common Lisp submissions have been extremely poorly written and indicative of someone who does not care to either learn or write proper Lisp code, so the submission should be vetted here, on the talk page, before he is allowed to post it on the task page. --Larry Hignight 03:49, 8 October 2012 (UTC)

Testing Common Lisp Contributions

Just to confirm my suspicions about the quality of Nigel's CL submissions, I decided to test both Ledrug and Nigel's current versions:

  • Ledrug's version:
    • Compiled on both CLISP and LispWorks without requiring any changes
    • Was extremely fast; In fact, it was faster than Nigel's 'vfast' C++ version for n = 1 million (.85s vs 1.20s)
      • The C++ compilation done with MinGW. The CL compilation with LispWorks. I did not set the compiler to optimize in either case.
  • Nigel's version:
    • Does not compile on CLISP: exit clause in DO must be a list
    • Does not compile on LispWorks: NIL does not match (SYSTEM::END-TEST-FORM &REST SYSTEM::RESULT-FORMS)

I'm sure that Nigel will respond to these results in his usual manner: "that is hot air", "all of your implementations are flawed; Mine is the only true Common Lisp", "Surely, you must have my version and Ledrug's version mixed up", or even the classic "Why didn't you just fix my code!" Who knows... I'm sure that it will be amusing though. Therefore, I encourage everyone with a working CL implementation to attempt to compile both versions and post your results. --Larry Hignight 07:45, 8 October 2012 (UTC)

I can identify three issues, none requiring any particular Lisp knowledge to resolve:

Issue the first

Sorry Paddy, you are probably going to have to pass the first to Michael. It is really a matter of editorial policy under what circumstances it is acceptable on rosetta code to call someone a "pompous dick" (if it is acceptable, how far may I go in responding?). Either way I can take it, boys will be boys. I don't know why ledrug chose to vomit over rosetta code, he seems to think his bile is reason, and to be suprised that it doesn't have the effect on me he thinks it should.

Issue the second

As Larry says "Anyone can view the history". Let's do so.

(cur | prev) 23:12, 19 September 2012? Ledrug (Talk | contribs)? m (84,428 bytes) (?Common Lisp: improve silly logic) (undo)
(cur | prev) 04:55, 19 September 2012? Ledrug (Talk | contribs)? (84,438 bytes) (?Common Lisp: reduce code; simplify; speed up; conform to task and extra) (undo)
(cur | prev) 00:12, 19 September 2012? Lhignight (Talk | contribs)? (88,507 bytes) (?Common Lisp: Updated the description of the 'fast' implementation.) (undo)
(cur | prev) 23:54, 18 September 2012? Lhignight (Talk | contribs)? (88,429 bytes) (Undo revision 140330 by Nigel Galloway (talk)) (undo)
(cur | prev) 23:52, 18 September 2012? Lhignight (Talk | contribs)? (90,240 bytes) (Undo revision 140337 by Paddy3118 (talk)) (undo)
(cur | prev) 23:50, 18 September 2012? Lhignight (Talk | contribs)? (90,151 bytes) (Undo revision 140331 by Nigel Galloway (talk)) (undo)
(cur | prev) 23:47, 18 September 2012? Lhignight (Talk | contribs)? (90,293 bytes) (Undo revision 140336 by Nigel Galloway (talk) See the CL section of the talk page for further discussion) (undo)
(cur | prev) 11:38, 9 July 2012? Nigel Galloway (Talk | contribs)? (79,959 bytes) (?Common Lisp) (undo)

I made a change to Larry's Common Lisp implemantation to make it work on 9 July 2012.

Nigel, my version did work. Your changes did NOT work and I wrote a number of bullets points addressing the issues with your version, which you chose to ignore, and instead responded to these valid concerns in an arrogant and pompous manner. You had the opportunity to respond to my criticism of your naming conventions, unnecessary use of globals (and later constants), use of setq, improper use of multiple-value-bind, poor readability/use of abrstaction, and other issues, including the FACT that your code FAILED to identify 9,999,999 as a Karprekar number. Instead, YOU chose to dismiss all of these valid concerns by stating that I was full of "hot air" and further suggest that the proper thing would have been for me to have fixed your version. --Larry Hignight 03:49, 8 October 2012 (UTC)

This stood until 18 September 2012, when Larry unidid the changes returning the implementation to a less than working solution.

Again, I undid your changes because the version that you posted was INCORRECT and BADLY WRITTEN Common Lisp. Your reference to my version as being 'less than a working solution' is another example of the bullshit comments that you continuously make in a vain attempt to deflect valid criticism of your submissions. --Larry Hignight 03:49, 8 October 2012 (UTC)

Ledrug completely replaced Larry's solution with a working example on 19 September 2012. For some reason Larry thinks I broke his solution and says "And for the record, Ledrug replaced YOUR version, not mine.". I think Larry is simply wrong in fact.

Nigel, YOU originally replaced my version starting this whole mess. Here is the precise order of events:
  • June 21 -- I (Larry) added a 2nd fast version that was quite a bit faster, easier to read, used additional Lisp forms AND only worked in base-10 (which is why I left the original version).
    • Both vesions were correct.
  • July 3 -- I (Larry) added the 'modular arithmetic filter' and additional output to the fast version that I had submitted.
  • July 9 -- You (Nigel) made three changes updates to my version; I was busy at the time had didn't have time to review your changes.
  • July 9 -- Paddy removed our names from the comment log.
  • Sept 18 -- After reviewing your version, which I found to be both incorrect and badly written, I undid you changes and posted why on the talk page.
    • You responded with the "hot air" comment and stated I should have fixed your code.
  • later, Ledrug submitted a single version, which he later updated with the mod filter, that was faster than mine, well-written, and worked for all number bases.
    • I believe Ledrug's current version is the best CL implementation of the task and should be the only version UNLESS someone using the code change criteria has valid reasons for changing it. --Larry Hignight 03:49, 8 October 2012 (UTC)

The problem is that ledrug replaced Larrys solution to, in ledrug's description "reduce code; simplify; speed up; conform to task and extra improve silly logic". This has made Larry angry, I think with the wrong person.

This is not true at all. First, you are the only person that I have been angry with due to your dismissive and insulting comments. Second, it is clear that Ledrug's 'silly logic' comment was in reference to a loop condition that he had written. --Larry Hignight 03:49, 8 October 2012 (UTC)

I would prefer that ledrug did not so overwrite someone elses work, but Larry seemed more interested in pointless abuse of me than improving and justifying his solution. Anyway I had a better idea.

Unbelievable. I wrote valid criticisms about the CORRECTNESS and READABILITY of the changes that YOU made to my submission. Something that you seem incapable of responding to in a professional manner. --Larry Hignight 03:49, 8 October 2012 (UTC)

Issue the third

I have identified 3 approaches to this task:

   1) a naive approach which loops over all numbers testing each fully for Kaprekarness; 
   2) a more sophiscated method which still loops over all numbers but implements a filter based on casting out nines which quickly eliminates seven nineths of the numbers; 
   3) realizing the nature of the uneliminated numbers it is possible to identify the residual sets to which possible Kaprekar numbers belong and generates them. 

ledrug's solution was of the first ilk, my better idea was to implemented a solution of the third. ledrug responded by upgrading his solution to type 2 and overwrote my solution with his. I recovered my solution and left ledrug's second solution in tact. He says's "then my edit you reverted" (sic), perhaps he didn't check the changes and thought I had deleted his - I had not. I may work further on this solution. I have noticed that the first 2 Kaprekars are in ran and that the test is simpler when it only needs to identify Kaprekars larger than Base. I have asked ledrug to leave this solution in place. I think he will comply even though he thinks saying please is bad manners. Larry didn't leave it, but I just put that down to vengence, the only reason he supplied is that ledrug has taught him to swear. I have supplied two good C++ solutions, but have not deleted the origional rather slow version. Ledrug has now implemented a fourth method, without deleting any one elses. Is that not better? --Nigel Galloway 13:15, 7 October 2012 (UTC)

Return to "Kaprekar numbers" page.