Talk:Two identical strings
task title
This (draft) task needs a better name, perhaps:
Decimal numbers whose binary version can be expressed as a concatenation of two identical binary literals.
Wordy and a bit verbose, but more accurate. -- Gerard Schildberger (talk) 10:04, 3 April 2021 (UTC)
task clarification
Obviously, 10 bits goes to 1024, and that's just over the limit of 1000. In the examples so far, "half" binary string literals are 1 to 5 digits long, each starting with one:
1 10, 11 100, 110, 101, 111 etc...
Doubling to:
11 1010, 1111 100100, 110110, 101101, 111111 etc...
Will it be permitted to do leading zeros on the "half" binary literals? Such as:
001, 010, 011, etc... 0001, 0010, 0011, etc... 00001, 00010, 00011, etc...
Doubling to:
001001, 010010, 011011, etc... 00010001, 00100010, 00110011, etc... 0000100001, 0001000010, 0001100011, etc...
And of course, are palindromes permitted?
example: 1001111001, 1100110011, etc..., and the like.
The two "halves" are still identical, just reversed.--Enter your username (talk) 10:55, 3 April 2021 (UTC)
Here is an example program to count the different ways: <lang csharp>using System; using static System.Console; using System.Collections.Generic; class Program {
static void fun(bool anylead, bool palin, bool verbose = false) { var res = new List<int>(); string s = "01", t; for (int a = 0; a < 2; a++) for (int b = 0; b < 2; b++) for (int c = 0; c < 2; c++) for (int d = 0; d < 2; d++) for (int e = 0; e < 2; e++) { t = "" + s[a] + s[b] + s[c] + s[d] + s[e]; for (int i = 0; i < 5; i++) { int x = Convert.ToInt32("" + t + t, 2); if (t[0] == '1' || anylead) if (!res.Contains(x) && x < 1000) { if (verbose) { Write("{0} ", "" + t + t); Write("({0}) ", x); } res.Add(x); } if (palin) { string tt = t; for (int j = t.Length - 1; j >= 0; j--) tt += t[j]; x = Convert.ToInt32(tt, 2); if (!res.Contains(x) && x < 1000) { if (verbose) {Write("{0} ", tt); Write("({0}) ", x); } res.Add(x); } } t = t.Substring(1); } } if (verbose) WriteLine(); Write(". {0,20}, {1,5} palindromes: ", anylead ? "any leading digit" : "only starts with '1'", palin ? "allow" : "no"); WriteLine(res.Count); res.Sort(); if (verbose) WriteLine(string.Join(" ", res)); }
static void Main(string[] args) { fun(true, true); fun(!true, true); fun(true, !true); fun(!true, !true); }
}</lang>
- Output:
. any leading digit, allow palindromes: 91 . only starts with '1', allow palindromes: 76 . any leading digit, no palindromes: 57 . only starts with '1', no palindromes: 30
--Enter your username (talk) 11:41, 3 April 2021 (UTC)
FreeBASIC black magic
The FreeBASIC solution to this task is super neat! Any chance for an explanation as to how/why it works? --Chunes (talk) 12:48, 3 April 2021 (UTC)
- log n/log 2 is the number of bits - 1 representing n in binary. The formula produces n shifted left by this number + 1, then adds n.--Nigel Galloway (talk) 15:24, 3 April 2021 (UTC)
- Chunes: Nigel Galloway's explanation is correct. (Thanks, Nigel.) To help me understand it, I've added an alternate FreeBASIC version that works without utilizing
log()
. The added variablep
(which represents2^int(log(n)/log(2)
) 'ratchets' up the left shift amount (theint(log(n)/log(2))
in2^int(log(n)/log(2))
) by double, so the2*n
ink=2*n*2^int(log(n)/log(2))
can just ben
, resulting ink = n*p
.--Enter your username (talk) 18:33, 4 April 2021 (UTC)
- These explanations are correct. To see how it works, suppose I want to duplicate 1001 (9 in decimal). First I multiply by two enough times that I end up with 10010000, then add the 1001 again. So I need to figure out the number of spare digits I need, which is (1+floor(log_2(9)). So I take my original number n, multiply by 2^(1+floor(log_2(n)), and add n. Thebigh (talk) 16:03, 5 April 2021 (UTC)