37
\$\begingroup\$

Given a list of digits 1 through 9, output whether each digit is grouped together as a single contiguous block. In other words, no two of the same digit are separated by different digits. It's OK if a digit doesn't appear at all. Fewest bytes wins.

Input: A non-empty list of digits 1 through 9. This can be as a decimal number, string, list, or similar sequence.

Output: A consistent Truthy value if all the digits are grouped in contiguous blocks, and a consistent Falsey value if they are not.

True cases:

3 51 44999911 123456789 222222222222222222222 

False cases:

818 8884443334 4545 554553 1234567891 

var QUESTION_ID=77608,OVERRIDE_USER=20260;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/77608/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>

\$\endgroup\$
5
  • 2
    \$\begingroup\$ Would a list of singleton strings be an acceptable input format? \$\endgroup\$ Commented Apr 12, 2016 at 0:22
  • \$\begingroup\$ Yes, singletons are fine. \$\endgroup\$ Commented Apr 12, 2016 at 1:31
  • \$\begingroup\$ Can anyone tell me what the most efficient algorithm for this problem would be? Or is there a more general problem that this falls under that I can look up? \$\endgroup\$ Commented Apr 14, 2016 at 12:36
  • \$\begingroup\$ @amt528 You can do it in linear time by iterating over each digit and checking that there's no runs of it past the first. \$\endgroup\$ Commented Apr 15, 2016 at 2:15
  • \$\begingroup\$ Could you provide an example of how it's implemented? \$\endgroup\$ Commented Apr 15, 2016 at 15:31

63 Answers 63

21
\$\begingroup\$

Python 3, 38 34 33 bytes

lambda s:s==sorted(s,key=s.index) 

This expects a list of digits or singleton strings as argument. Test it on Ideone.

Thanks to @xsot for golfing off 4 bytes!

Thanks to @immibis for golfing off 1 byte!

\$\endgroup\$
6
  • \$\begingroup\$ If you are allowed to accept a list of strings instead, you can shorten this to lambda s:s==sorted(s,key=`s`.find) \$\endgroup\$ Commented Apr 12, 2016 at 0:19
  • \$\begingroup\$ Ah, I tried taking a list, but I didn't think of using backticks... I'll ask the OP. \$\endgroup\$ Commented Apr 12, 2016 at 0:22
  • \$\begingroup\$ Am I missing something - why can't you just use s.find? \$\endgroup\$ Commented Apr 12, 2016 at 4:31
  • \$\begingroup\$ @immibis s has to be a list of singleton strings (or I'd have to cast s to list for the comparison), and list.find is not defined... \$\endgroup\$ Commented Apr 12, 2016 at 4:33
  • \$\begingroup\$ @Dennis s.index then? Seems to work for me. \$\endgroup\$ Commented Apr 12, 2016 at 4:37
15
\$\begingroup\$

JavaScript (ES6), 27 bytes

s=>!/(.)(?!\1).*\1/.test(s) 

Uses negative lookahead to look for two non-contiguous digits. If at least two such digits exist, then they can be chosen so that the first digit precedes a different digit.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Or, just use a regex XD. That works too. \$\endgroup\$ Commented Apr 12, 2016 at 0:01
  • 1
    \$\begingroup\$ ahem Retina ahem \$\endgroup\$ Commented Apr 12, 2016 at 5:58
14
\$\begingroup\$

05AB1E, 4 bytes

Code:

Ô¹ÙQ 

Explanation:

Ô # Push connected uniquified input. E.g. 111223345565 would give 1234565. ¹ # Push input again. Ù # Uniquify the input. E.g. 111223345565 would give 123456. Q # Check if equal, which yields 1 or 0. 

Uses CP-1252 encoding.

Try it online!

\$\endgroup\$
1
  • 2
    \$\begingroup\$ You...just beat jelly...I never thought this was possible... \$\endgroup\$ Commented Apr 15, 2016 at 8:17
13
\$\begingroup\$

Jelly, 5 bytes

ĠIFPỊ 

Try it online!

How it works

ĠIFPỊ Main link. Input: n (list of digits or integer) Ġ Group the indices of n by their corresponding values, in ascending order. For 8884443334, this yields [[7, 8, 9], [4, 5, 6, 10], [1, 2, 3]]. I Increments; compute the all differences of consecutive numbers. For 8884443334, this yields [[1, 1], [1, 1, 4], [1, 1]]. F Flatten the resulting 2D list of increments. P Product; multiply all increments. Ị Insignificant; check if the product's absolute value is 1 or smaller. 
\$\endgroup\$
2
  • \$\begingroup\$ Five bytes you say? What kind of encoding is that? \$\endgroup\$ Commented Apr 12, 2016 at 5:56
  • 5
    \$\begingroup\$ Jelly has its own code page, which encodes each of the 256 characters it understands as a single byte. \$\endgroup\$ Commented Apr 12, 2016 at 5:57
9
\$\begingroup\$

Pyth, 6 5 bytes

1 bytes thanks to FryAmTheEggman

SIxLQ 

Inspired by the Python solution here.

Test suite

Explanation:

SIxLQ xLQ Map each element in the input to its index in the input. Input is implicit. SI Check whether this list is sorted. 
\$\endgroup\$
3
  • 3
    \$\begingroup\$ SIxLQ seems to work. \$\endgroup\$ Commented Apr 12, 2016 at 1:12
  • \$\begingroup\$ This is genius. \$\endgroup\$ Commented Apr 12, 2016 at 1:52
  • 1
    \$\begingroup\$ The second Q doesn't seem to get parsed properly, it swaps argument order or something so you get all 0s and it always gives true. Here's a test suite. \$\endgroup\$ Commented Apr 12, 2016 at 1:55
9
\$\begingroup\$

MATL, 8 bytes

t!=tXSP= 

The output is an array containing only ones for truthy, or an array containing at least one zero for falsey.

Try it online!

Explanation

Consider the input 22331, which satisfies the condition. Testing if each character equals each other gives the 2D array

1 1 0 0 0 1 1 0 0 0 0 0 1 1 0 0 0 1 1 0 0 0 0 0 1 

The final result should be truthy if the rows of that array (with rows considered as atomic) are in decreasing lexicographical order. For comparison, input 22321 gives the array

1 1 0 1 0 1 1 0 1 0 0 0 1 0 0 1 1 0 1 0 0 0 0 0 1 

in which the rows are not in order.

t! % Take string input. Duplicate and tranpose = % Test for equality, element-wise with broadcast: gives a 2D array % that contains 0 or 1, for all pairs of characters in the input t % Duplicate XS % Sort rows (as atomic) in increasing order P % Flip vertically to obtain decreasing order = % Test for equality, element-wise 
\$\endgroup\$
8
\$\begingroup\$

R, 66 48 46 43 38 bytes

function(s)!any(duplicated(rle(s)$v)) 

This is a function that accepts the input as a vector of digits and returns a boolean. To call it, assign it to a variable.

Not the shortest but I thought it was a fun approach. We run length encode the input and extract the values. If the list of values contains duplicates then return FALSE, otherwise return TRUE.

Verify all test cases online

Saved 20 bytes thanks to MickyT, 3 thanks to Albert Masclans, and 5 thanks to mnel!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ 26 by switching to latest R version and using table. \$\endgroup\$ Commented Aug 21, 2022 at 18:36
6
\$\begingroup\$

Retina, 17 bytes

M`(.)(?!\1).+\1 0 

Try it online! (Slightly modified to run all test cases at once.)

The first regex matches digits which are separated by other digits, so we get a 0 for valid inputs and anywhere between 1 and 9 for invalid inputs (due to the greediness of the the .+, we can't get more than n-1 matches for n different digits).

To invert the truthiness of the result, we count the number of 0s, which is 1 for valid inputs and 0 for invalid ones.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ I made a shorter one, but it's close enough to yours that it should be a comment instead. Use AntiGrep instead of Match, then remove the last line: A`(.)(?!\1).+\1 for 15 bytes. Also works for multiple inputs. Truthy is the input, falsy is nothing. One does not simply out-golf Martin at his own language. :) \$\endgroup\$ Commented Apr 22, 2016 at 19:11
  • 1
    \$\begingroup\$ @mbomb007 I think I actually considered that, but unfortunately, the challenge asks for a consistent truthy (and falsy) value, so printing the input as truthy isn't allowed. \$\endgroup\$ Commented Apr 22, 2016 at 19:43
6
\$\begingroup\$

J, 8 bytes

-:]/:i.~ 

Test it with J.js.

How it works

-:]/:i.~ Monadic verb. Argument: y (list of digits) i.~ Find the index in y of each d in y. ]/: Sort y by the indices. -: Match; compare the reordering with the original y. 
\$\endgroup\$
2
  • 1
    \$\begingroup\$ :] :i :-1 \$\endgroup\$ Commented Apr 13, 2016 at 2:02
  • 11
    \$\begingroup\$ Not sure if joke or golfing suggestion... \$\endgroup\$ Commented Apr 13, 2016 at 2:19
6
\$\begingroup\$

Vyxal, 4 bytes

)ġf⁼ 

Try it Online!

Takes input as a list of singleton strings. Happens to be a different algorithm to the existing vyxal answer.

Explained

)ġf⁼­⁡​‎‎⁡⁠⁡‏⁠‎⁡⁠⁢‏‏​⁡⁠⁡‌⁢​‎‎⁡⁠⁣‏‏​⁡⁠⁡‌⁣​‎‎⁡⁠⁤‏‏​⁡⁠⁡‌­ )ġ # ‎⁡Group by the identity function, by order of first appearance. f # ‎⁢Flatten the list ⁼ # ‎⁣Does that equal the input? 💎 
\$\endgroup\$
2
  • \$\begingroup\$ what is the diamond emoji for? 💎 \$\endgroup\$ Commented Jul 4, 2023 at 16:54
  • \$\begingroup\$ It means it was created with the help of Luminespire \$\endgroup\$ Commented Jul 4, 2023 at 17:58
5
\$\begingroup\$

Ruby, 23 bytes

Anonymous function. Accepts a string. Regex strat.

->n{/(.)(?!\1).*\1/!~n} 

Regex breakdown

/(.)(?!\1).*\1/ (.) # Match a character and save it to group 1 (?!\1) # Negative lookahead, match if next character isn't # the same character from group 1 .* # Any number of matches \1 # The same sequence as group 1 

!~ means if there are no matches of the regex within the string, return true, and otherwise return false.

\$\endgroup\$
5
\$\begingroup\$

Java, 161 156 bytes

Because Java...

Shamelessly stealing borrowing the regex from this answer because I started out trying to do this with arrays and math manipulation, but it got hideously complex, and regex is as good a tool as any for this problem.

import java.util.regex.*;public class a{public static void main(String[] a){System.out.println(!Pattern.compile("(.)(?!\\1).*\\1").matcher(a[0]).find());}} 

Ungolfed:

import java.util.regex.*; public class a { public static void main(String[] args) { System.out.println(!Pattern.compile("(.)(?!\\1).*\\1").matcher(args[0]).find()); } 

Laid out like a sensible Java person:

import java.util.regex.Matcher; import java.util.regex.Pattern; public class { public static void main(String[] args) { Pattern p = Pattern.compile("(.)(?!\\1).*\\1"); Matcher m = p.matcher(args[0]); System.out.println(!m.find()); } } 
\$\endgroup\$
3
  • 3
    \$\begingroup\$ like a sensible Java person That would be, not using Java ever. \$\endgroup\$ Commented Apr 13, 2016 at 20:07
  • \$\begingroup\$ Other solutions are just providing a function, would make it a lot shorter. Something like s->s.match("(.)(?!\\1).*\\1") \$\endgroup\$ Commented Apr 13, 2016 at 21:47
  • 2
    \$\begingroup\$ But then we couldn't revel in the verboseness of the answer. \$\endgroup\$ Commented Apr 14, 2016 at 0:54
5
\$\begingroup\$

Regex (Perl / PCRE / Java / Boost / Pythonregex / Ruby), 17 bytes

^(?!(.)+\1*+.+\1) 

Try it online! - Perl
Try it online! - PCRE
Try it online! - Java
Try it online! - Boost
Try it online! - Python import regex
Try it online! - Ruby

^ # Anchor to start of string (?! # Assert that the following can't match: (.)+ # Skip any number of characters (minimum zero), then capture # the next character in \1 \1*+ # Skip all subsequent occurrences of \1, and lock in that match # using a possessive quantifier. .+ # Skip at least one character, or as many as necessary to make the # following match: \1 # Match the character captured in \1 ) 

Regex (Perl / PCRE / Java / Boost / Pythonregex / Ruby), 11 bytes

(.)\1*+.+\1 

Returns a match for false, and a non-match for true.

Try it online! - Perl
Try it online! - PCRE
Try it online! - Java
Try it online! - Boost
Try it online! - Python import regex
Try it online! - Ruby

This beats the regex in the previous Java answer, Perl answer, and Ruby answer by 2 bytes.

(.) # \1 = a character anywhere in the string \1*+ # Skip all subsequent occurrences of \1, and lock in that match using a # possessive quantifier. .+ # Skip at least one character, or as many as necessary to make the # following match: \1 # Match the character captured in \1 

Regex (ECMAScript (or better) / Python / .NET), 13 bytes

(.)(?!\1).+\1 

Returns a match for false, and a non-match for true.

Try it online! - ECMAScript
Try it online! - Perl
Try it online! - PCRE
Try it online! - Java
Try it online! - Boost
Try it online! - Python
Try it online! - Python import regex
Try it online! - Ruby
Try it online! - .NET

\$\large\textit{Anonymous functions}\$

Ruby, 21 bytes

->s{/(.)\1*+.+\1/!~s} 

Try it online!

JavaScript (ES6), 27 bytes

s=>!/(.)(?!\1).+\1/.test(s) 

Try it online!

Included for completeness; already done in Neil's answer.

PowerShell, 29 bytes

!($args-match'(.)(?!\1).+\1') 

Try it online!

Julia v0.7+, 30 bytes

s->!occursin(r"(.)\1*+.+\1",s) 

Attempt This Online! / Try it online!

Julia v1.3+, 28 bytes

s->count(r"(.)\1*+.+\1",s)<1 

Attempt This Online!

-2 bytes compared to v0.7+, thanks to MarcMush

R, 32 bytes

\(s)!grepl('(.)\\1*+.+\\1',s,,1) 

Attempt This Online!

Beaten by Alex A.'s non-regex answer by 2 bytes, or by 6 bytes with pajonk's improvement.

Java, 33 bytes

s->!s.matches("(.)+\\1*+.+\\1.*") 

Try it online!

PHP, 39 bytes

fn($s)=>!preg_match('/(.)\1*+.+\1/',$s) 

Try it online!

\$\large\textit{Full programs}\$

Perl -p, 17 bytes (18 bytes including flag)

$_=!/(.)\1*+.+\1/ 

Try it online!

Retina 0.8.2, 17 bytes

M`(.)(?!\1).+\1 0 

Try it online!

Included for completeness; already done in Martin Ender's answer.

Retina 1.0, 17 bytes

C`(.)(?!\1).+\1 0 

Try it online!

Pip, 19 18 bytes

`(.)(?!\1).+\1`NIa 

Try it online!

Thanks to DLosc.

\$\endgroup\$
5
  • 1
    \$\begingroup\$ Alex A.'s answer does work correctly but takes vector of digits/characters as input, but can be 26 \$\endgroup\$ Commented Aug 21, 2022 at 18:36
  • \$\begingroup\$ @pajonk Thanks, edited. It also works with utf8ToInt() instead of el(strsplit(,"")). \$\endgroup\$ Commented Aug 21, 2022 at 18:51
  • 1
    \$\begingroup\$ 13 bytes in Python re flavor with match = falsey / no match = truthy: (.)(?!\1).+\1 (Try it online!) \$\endgroup\$ Commented Aug 21, 2022 at 20:47
  • 1
    \$\begingroup\$ (Note: the Pip program can be 18 bytes because the space isn't necessary.) \$\endgroup\$ Commented Sep 3, 2022 at 5:16
  • 1
    \$\begingroup\$ Julia, 28 bytes: s->count(r"(.)\1*+.+\1",s)<1 \$\endgroup\$ Commented Jul 3, 2023 at 8:26
5
\$\begingroup\$

Haskell, 37 bytes

f l=(==)=<<scanl1 min$(<$>l).(==)<$>l 

Try it online!

Uses the same approach as Luis Mendo's MATL answer: creates a vector for each entry which indices equal it, and checks that the result is sorted in decreasing order.

(<$>l).(==)<$>l is shorter version of [map(==a)l|a<-l]. The function (<$>l).(==) that takes a to map(==a)l is mapped onto l.

scanl1 min takes the cumulative smallest elements of l, which equals the original only if l is reverse-sorted. (==)=<< checks if the list is indeed invariant under this operation.

A recursive strategy also gave 37 bytes:

f(h:t)=t==[]||f t>(elem h t&&h/=t!!0) 

Try it online!

This checks each suffix to see if its first element doesn't appear in the remainder, excusing cases where the first two elements are equal as part of a contiguous block.

Other approaches:

42 bytes

f l=and[all(/=a)t|a:b:t<-scanr(:)[]l,a/=b] 

Try it online!

43 bytes

import Data.List ((==)<*>nub).map nub.group 

Try it online!

\$\endgroup\$
5
\$\begingroup\$

Jelly, \$_4\$ 3 bytes

nÞƑ 

Try it online!

Semi-based on several of DLosc's 5-byters.

 Ƒ The input is not changed by Þ sorting its elements by n the list of, for each element, if it is not equal to that element. 

Kind of like cutting the F out of ¹ƙ`F⁼, but also kind of like cutting the `ṢƑ out of iⱮ`ṢƑ. Compared to the previous i@ÞƑ, it simply saves an @ by using lexicographic comparisons with a dyad that doesn't discriminate between its left and right argument instead of numeric comparisons with one that does--the first index of an element is the first position at which its inequality-vector has a zero, so one element has a greater first index than another iff its inequality-vector is all ones up to the position where the other's has its first zero.

It's been almost 3 years, and ðƙF⁼ still makes me so sad...!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ @thejonymyster Should be clearer now \$\endgroup\$ Commented Aug 21, 2022 at 19:05
  • 1
    \$\begingroup\$ What a clever 4 -> 3 golf! :o \$\endgroup\$ Commented Aug 11 at 16:02
4
\$\begingroup\$

Pyth, 7 bytes

{IeMrz8 

Test Suite.

\$\endgroup\$
4
\$\begingroup\$

Mathematica, 26 bytes

0<##&@@Sort[#&@@@Split@#]& 
\$\endgroup\$
4
\$\begingroup\$

MATL, 13 11 bytes

u"G@=fd2<vA 

Thanks to Luis Mendo for saving two bytes!

Try it Online!

Explanation

 % Grab the input implicitly u % Find the unique characters " % For each of the unique characters G % Grab the input again @= % Determine which chars equal the current char f % Find the locations of these characters d % Compute the difference between the locations 2< % Find all index differences < 2 (indicating consecutive chars) v % Vertically concatenate all stack contents A % Ensure that they are all true % Implicit end of the for loop 
\$\endgroup\$
3
  • \$\begingroup\$ You can take the input with quotes (allowed by default) and remove j. Also, I think you can move vA within the loop and remove ] \$\endgroup\$ Commented Apr 12, 2016 at 8:52
  • \$\begingroup\$ @LuisMendo Thanks! I had messed around with putting Y& inside but that didn't work because fd2< can be empty. Moving vA inside works great though! Also I really wish we had a stable unique that didn't take up tons of bytes. \$\endgroup\$ Commented Apr 12, 2016 at 11:24
  • \$\begingroup\$ Now stable unique takes a little less, using a number instead of the predefined string. I may add a shorter version in the future, though. Or just make u stable by default (you could always include S afterwards, two bytes). What do you think? \$\endgroup\$ Commented Apr 12, 2016 at 12:13
4
\$\begingroup\$

Vyxal, 4 bytes

vḟÞṠ 

Try it Online!

vḟ # Index of B in A, vectorized (B will be each individual character in the # string / item in the list, and A will be the string/list itself) ÞṠ # Is the result sorted? 

Answers that use this method, in chronological order:

Vyxal, 5 bytes

₌ÞǓU= 

Try it Online!

₌ # Parallel Apply - apply the following two elements to the input and keep # both results on the stack. ÞǓ # Connected Uniquify - Remove occurences of adjacent duplicates. U # Uniquify - Remove all duplicates. = # Are the two results equal? 

Turned out to be a port of Adnan's 05AB1E answer.

\$\endgroup\$
4
\$\begingroup\$

Uiua, 6 bytes

≍⊝.⊜⊢. 

Try it!

≍⊝.⊜⊢. ⊜⊢. # get the first digit in each like contiguous group . # duplicate ⊝ # deduplicate ≍ # do they match? 
\$\endgroup\$
4
\$\begingroup\$

Jelly, 4 bytes

ĠIỊȦ 

Try it online!

Explanation

An independently derived variation on Dennis's 5-byte answer:

ĠIỊȦ Ġ Group indices 1..N based on their values in the input list I Get the difference of each pair of adjacent values in those lists Ị For each difference, 1 if it is <= 1, 0 if it is greater than 1 Ȧ 0 if the nested list contains any 0s, 1 otherwise 
\$\endgroup\$
4
+100
\$\begingroup\$

Regenerate -c, 103 94 87 bytes

((${$2/10}!$~1)($4!)(${$2%10})($0{$3-$4}!(${$6*$7}!1)(${$4*6+5})0{$6-$6/$7*$7-1})){#~1} 

Outputs 0 for falsey, 1 for truthy. As of this writing, ATO doesn't have the -c flag yet, so the program there outputs nothing for falsey and a string of digits for truthy. Attempt This Online!

Explanation

Inspired by Unrelated String's answer, I thought of a different way to track whether a digit has been seen already: mapping each digit to a different prime number and storing their product. Then I realized that the numbers only needed to be coprime, which saved even more bytes.

(...){#~1} 

Repeat the following a number of times equal to the length of the input:

(${$2/10}!$~1) 

Group 2 stores the input number and removes one digit at a time from the right end. If group 2 has been matched before, ${$2/10} matches the previous value int-divided by 10; if not (which is only the case on the first iteration), $~1 matches the input.

($4!) 

Group 3 stores the previous digit. It matches the previous value of group 4, or empty string if group 4 has not matched before.

(${$2%10}) 

Group 4 stores the current digit, i.e. the rightmost digit of the current number in group 2.

($0{$3-$4}!...) 

Group 5 starts by testing if the difference between group 3 and group 4 is zero, i.e. if we have two consecutive identical digits. If so, we repeat the nonexistent group 0 zero times; this succeeds, matching empty string, and we proceed to the next iteration. If not, trying to match group 0 (or repeat it a negative number of times) fails, and we proceed to the alternate branch, where we process a new digit:

(${$6*$7}!1) 

Group 6 stores the product of coprimes. If groups 6 and 7 have been matched before, ${$6*$7} multiplies them and sets that as the new value of group 6. If not, we use 1 as the initial value.

(${$4*6+5}) 

Group 7 stores the coprime number representing the current digit. We map the value of group 4, a digit between 1 and 9, to the corresponding number from this arithmetic progression: 11, 17, 23, 29, 35, 41, 47, 53, 59. All of them are prime except 35, which doesn't have any of the others as factors.

0{$6-$6/$7*$7-1} 

Now we check whether the current digit has been seen before. If it has, we know that it wasn't just now because the previous digit is different, which means we want the match to fail.

$6/$7*$7 int-divides the product of coprimes in group 6 by the most recent coprime in group 7 and then multiplies it by this coprime again. If the current digit has been seen before, the division is exact, and multiplying gives the original value of group 6 back; otherwise, the division truncates the result, and multiplying gives a number smaller than the original value.

0{$6-...-1} subtracts the above quantity from group 6 and then subtracts 1. This results in -1 if the current digit has been seen before and a nonnegative number if it has not. We then use that number as a repetition count for an arbitrary character. If the number is negative, the regex fails, outputting 0 successful matches. If there are no failures in any iteration, the regex outputs 1 successful match.

\$\endgroup\$
3
\$\begingroup\$

Haskell, 44 bytes

import Data.List ((==)<*>nub).map head.group 

Usage example: ((==)<*>nub).map head.group $ "44999911" -> True.

A non-pointfree version:

f x = q == nub q -- True if q equals q with duplicates removed where q = map head $ group x -- group identical digits and take the first -- e.g. "44999911" -> ["44","9999","11"] -> "491" -- e.g "3443311" -> ["3","44","33","11"] -> "3431" 
\$\endgroup\$
3
\$\begingroup\$

Python, 56 55 bytes

a=lambda s:~(s[0]in s.lstrip(s[0]))&a(s[1:])if s else 1 
\$\endgroup\$
2
  • \$\begingroup\$ Fails in Python 3.4.1 (int not subscriptable) \$\endgroup\$ Commented Apr 13, 2016 at 1:38
  • \$\begingroup\$ Saved an extra byte with ~(which literally is equivalent to1-): a=lambda s:~(s[0]in s.lstrip(s[0]))&a(s[1:])if s else 1 \$\endgroup\$ Commented Apr 13, 2016 at 1:53
3
\$\begingroup\$

C#, 119 bytes

bool m(String s){for(int i=0;i<9;i++){if(new Regex(i.ToString()+"+").Matches(s).Count>1){return false;}}return true;} 

Ungolfed

bool m(String s) { for(int i=0;i<9;i++) { if(new Regex(i.ToString() + "+").Matches(s).Count > 1) { return false; } } return true; } 
\$\endgroup\$
3
  • 1
    \$\begingroup\$ Welcome to PPCG! Instead of deleting a post and making a new post with the fixed version, you could also edit your old post and then undelete it. (No need to do that now that there's two posts already anyway, but just so you know in the future.) \$\endgroup\$ Commented Apr 14, 2016 at 13:06
  • \$\begingroup\$ My bad. When I first intended to participate in this Code Golf I misread the objective and didn't had much time to do another solution ( and knowing myself, I wouldn't try to correct the previous posted solution ). But then I was told I had some more time free and attempted to post the "correct solution". Didn't even thought in doing what you said. Next time I'll have that in mind! \$\endgroup\$ Commented Apr 14, 2016 at 14:11
  • \$\begingroup\$ No problem at all, I hope you'll have a good time in the community. :) \$\endgroup\$ Commented Apr 14, 2016 at 14:13
3
\$\begingroup\$

BQN, 9 5 bytes

≡⟜∧⊐˜ 

Anonymous tacit function. Takes a string or a list of integers. Try it at BQN online!

Explanation

Inspired by Dennis's J answer, though the details are a bit different.

Given two lists, works as follows: for each element of its right argument, it finds the first index of that value in its left argument.

We're using ⊐˜, which passes the same list as both left and right arguments. The result is a list, for each digit, of the index of that digit's first occurrence.

If the digits are grouped together, these indices will occur in ascending order. However, if some copies of digit A are separated by digit B, B's (larger) index will come between the copies of A's (smaller) index.

≡⟜∧⊐˜ ⊐˜ First index of each digit in the argument list ≡⟜ The result is identical to ∧ The result, sorted ascending 
\$\endgroup\$
3
\$\begingroup\$

K (ngn/k), 11 10 bytes

-1 byte thanks to @ovs

~/,/'='^:\ 

Try it online!

^: test for spaces - always returns 0s, as the input consists only of digits. The : here means monadic.

^:\ repeat until convergence. This will return a pair of the original argument and a list of 0s of the same length as the argument.

=' group each. To "group" a list means to make a dictionary that maps each distinct element of the list to the positions where it occurs.

,/' raze each, i.e. ignore the keys and concatenate the values. For the list of all 0s this will result in 0,1,...,length-1. For the other list, it will depend on the presence of non-continuous blocks - if there aren't any, the result will be 0,1,...,length-1 too.

~/ do they match?

\$\endgroup\$
2
  • 1
    \$\begingroup\$ I think the #:'\ can be ^:\ \$\endgroup\$ Commented Aug 21, 2022 at 12:52
  • \$\begingroup\$ @ovs well spotted, thanks! \$\endgroup\$ Commented Aug 21, 2022 at 13:57
3
\$\begingroup\$

Brachylog, 5 4 bytes

≡ᵍc? 

Try it online!

-1 thanks to DLosc

Takes input as a list of digits through the input variable, and succeeds or fails as output.

≡ᵍ The input with identical elements grouped in order of first appearance c with the groups concatenated ? is the input. 
\$\endgroup\$
0
3
\$\begingroup\$

Prolog (SWI), 40 bytes

\[A|S]:-S=[];(S=[A|_];\+member(A,S)),\S. 

Try it online!

-3 thanks to Jo King

Similar to xnor's second Haskell answer.

This won't work on TIO because it is too old of a version, and it's longer, but I think it's more interesting:

Prolog (SWI), 57 bytes

\A:-clumped(A,B),maplist([X-_,X]>>!,B,C),list_to_set(A,C). 
\$\endgroup\$
0
3
\$\begingroup\$

Arturo, 28 22 bytes

$=>[=unique<=squeeze&] 

Try it!

$=>[ ; a function where input is assigned to & squeeze& ; squeeze the input; e.g. [1 1 2 1 1 1 3 3] -> [1 2 1 3] <= ; duplicate unique ; remove duplicates = ; are they equal? ] ; end function 
\$\endgroup\$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.