Offset in split text content

7

You will be given an ASCII text. This text may have zero, one or many appearances of a split a character (let's assume it will be the space character )
You will also be given an offset integer value (zero based) anywhere between zero and the length of the text.

You should calculate the relative offset inside the one split text, which contains the absolute offset, as well as the index of that very split text.
If the given offset is at the split character the last split should have the offset

It's hard to describe (comments welcome), so here are some examples

text: Lorem ipsum dolor sit amet
offset: 20

Lorem ipsum dolor sit amet
enter code here
--------------------^
000000000011111111112
012345678901234567890

Result: 2, 3
Explanation: If we split the text along the space characters, the split text, where the offset is in, is the fragment `sit` which is the 3rd split (count starts at zero) and the offset inside this fragment is 2  
sit
--^
012

Some more examples

Text                           Offset        Result
Lorem ipsum dolor sit amet     0             0, 0
^
Lorem ipsum dolor sit amet     1             1, 0
-^
Lorem ipsum dolor sit amet     2             2, 0
--^
Lorem ipsum dolor sit amet     3             3, 0
---^
Lorem ipsum dolor sit amet     4             4, 0
----^
Lorem ipsum dolor sit amet     5             5, 0
-----^
Lorem ipsum dolor sit amet     6             0, 1
------^
Lorem ipsum dolor sit amet     7             1, 1
-------^
Lorem ipsum dolor sit amet     8             2, 1
--------^
Lorem ipsum dolor sit amet     9             3, 1
---------^
Lorem ipsum dolor sit amet     10            4, 1
----------^
Lorem ipsum dolor sit amet     11            5, 1
-----------^
Lorem ipsum dolor sit amet     12            0, 2
------------^
Lorem ipsum dolor sit amet     13            1, 2
-------------^
Lorem ipsum dolor sit amet     14            2, 2
--------------^
Lorem ipsum dolor sit amet     15            3, 2
---------------^
Lorem ipsum dolor sit amet     16            4, 2
----------------^
Lorem ipsum dolor sit amet     17            5, 2
-----------------^
Lorem ipsum dolor sit amet     18            0, 3
------------------^
Lorem ipsum dolor sit amet     19            1, 3
-------------------^
Lorem ipsum dolor sit amet     20            2, 3
--------------------^
Lorem ipsum dolor sit amet     21            3, 3
---------------------^
Lorem ipsum dolor sit amet     22            0, 4
----------------------^
Lorem ipsum dolor sit amet     23            1, 4
-----------------------^
Lorem ipsum dolor sit amet     24            2, 4
------------------------^
Lorem ipsum dolor sit amet     25            3, 4
-------------------------^
Lorem ipsum dolor sit amet     26            4, 4
--------------------------^

yunzen

Posted 2019-03-19T09:28:26.997

Reputation: 203

If I am correctly interpreting your example, the second integer is the number of split characters in the first offset characters, the first is the character that is hit inside the chunk counted from its own origin? Do the two have anything in common? – Jonathan Frech – 2019-03-19T10:21:30.257

@JonathanFrech I assume your thought on the second integer is correct. I don't understand your thought on the first character. And what do you mean by Do the two have anything in common?? – yunzen – 2019-03-19T10:24:49.457

To me, the question appears to simply be two properties of a piece of text mangled together; I wanted to ask if there is any semantic connection between the two output integers. – Jonathan Frech – 2019-03-19T10:28:07.003

You want to now the reason why I ask this? It's inspired by this question on SE: https://stackoverflow.com/questions/55235774/text-area-getting-accurate-cursor-position-on-resize And I thought it would be an interesting question on CG

– yunzen – 2019-03-19T10:42:47.167

Can we use 1 indexed instead of 0 indexed – Graham – 2019-03-19T10:45:11.923

I'd prefer 0 but I'm not bound to it – yunzen – 2019-03-19T10:45:43.140

5

"It's hard to describe (comments welcome)". This is why the Sandbox exists. When you want to create challenges, first lay them in the sandbox and let other people help you refine it.

– Olivier Grégoire – 2019-03-19T13:56:24.973

Answers

3

Python 3.8, 56 bytes

lambda a,b:(x:=a[:b].split(' '))and[len(x[-1]),len(x)-1]

Try it online!

Jonas Ausevicius

Posted 2019-03-19T09:28:26.997

Reputation: 311

3

Perl 5, 47 44 bytes

$_=substr$_,0,<>;/.* /;$_=$'=~y///c.$".y/ //
  • $_=substr$_,0,<>; to extract first n (from nextline <>) characters of input $_ and store in default argument.
  • /.* / to match largest string ending with space
  • $_=$'=~y///c.$".y/ // default argument $_ (which will be printed -p option) is set with concatenation . of length of post-match : $'=~y///c, $" space (list argument delimiter when interpolated betwen double quotes), and y/ // number of spaces in current default argument.

TIO

Nahuel Fouilleul

Posted 2019-03-19T09:28:26.997

Reputation: 5 582

Oh wow! How very cryptic of you – yunzen – 2019-03-19T13:43:50.523

3

Stax, 5 bytes

╓ò)♣*

Run and debug it

Unpacked, ungolfed, and commented, it looks like this.

(       trim string to length
j       split on spaces
N       remove last element from array and push separately
W       until the stack is empty...
  %P    pop element and print its length

Run this one

recursive

Posted 2019-03-19T09:28:26.997

Reputation: 8 616

2

05AB1E, 9 bytes

£ð¡¤gsg<‚

Port of @JonasAusevicius's Python 3.8 answer, so make sure to upvote him as well!

Try it online or verify all test cases.

Explanation:

£         # Only leave the first (implicit) input-integer amount of characters
          #  of the (implicit) string-input
 ð¡       # Split this by spaces
          # (Note: builtin `#` doesn't work here, because a string without spaces
          #  would not be wrapped in a list)
   ¤g     # Get the length of the last string in the list (without popping the list itself)
     sg<  # Swap to get the list again, and get it's length minus 1
        ‚ # Pair both integers (and output the result implicitly)

Kevin Cruijssen

Posted 2019-03-19T09:28:26.997

Reputation: 67 575

2

JavaScript (Node.js), 75 70 69 70 68 67 bytes

t=>o=>[o+~(s=t.substr(0,o)).lastIndexOf(' '),s.split(' ').length-1]

Try it online!

No space parameter, only hardcoded (+ 2 bytes)
-2 bytes thanks to inspiration from the Java answer by Kevin Cruijssen
-1 byte thanks to zevee

yunzen

Posted 2019-03-19T09:28:26.997

Reputation: 203

1o-s.lastIndexOf(d)-1 can be o+~s.lastIndexOf(d) to save a byte (here the relevant tip). – Kevin Cruijssen – 2019-03-19T12:51:16.443

Also, you take the space as input, but all the others answers thus far hardcoded the space. So either the challenge should mention a third split-character is required as input, or this answer could also hardcode the space. Not sure which of the two you intended when you made the challenge? – Kevin Cruijssen – 2019-03-19T12:56:06.300

@KevinCruijssen I used a hardcoded space now – yunzen – 2019-03-19T13:01:21.210

1You can do t=>o=> instead of (t,o)=> to save a byte and then take input as f(t)(o) – vityavv – 2019-03-19T17:18:17.070

2

C# (Visual C# Interactive Compiler), 79 77 75 63 60 bytes

a=>b=>((a=a.Substring(0,b).Split())[b=a.Length-1].Length,b);

8 bytes saved thanks to Kevin Cruijssen and a further 3 bytes saved thanks to Embodiment of Ignorance

Try it online!

Expired Data

Posted 2019-03-19T09:28:26.997

Reputation: 3 129

73 bytes – Kevin Cruijssen – 2019-03-19T14:18:02.687

1Cut another 10 using dynamic and saving the extra split – Expired Data – 2019-03-19T14:25:04.497

Oh smart! I need to remember that. – Kevin Cruijssen – 2019-03-19T14:31:52.640

1

APL+WIN, 33 bytes

(1++/m),n-¯1↑(m←(m←n↑⎕)=' ')/⍳n←⎕

Try it online! Courtesy of Dyalog Classic

1 Indexed

Prompts for index of character in full text string followed by string

Outputs index of character in nth substring and substring number

Graham

Posted 2019-03-19T09:28:26.997

Reputation: 3 184

1

Java 8, 83 75 bytes

n->s->n+~(s=s.substring(0,n)).lastIndexOf(" ")+","+~-s.split(" ",-1).length

-8 bytes implicitly thanks to inspiration from @yunzen's JavaScript answer.

Try it online.

Explanation:

n->s->                   // Method with integer & String parameters and String return-type
  n+~                    //  Return `n` minus 1, minus the following:
     (s=s.substring(0,n))//   Set `s` to the first `n` characters of input-String `s`
      .lastIndexOf(" ")  //   and get the index of the last space
  +","                   //  Appended with a comma-delimiter
     s.split(" ",        //  Split the new `s` by spaces
                 -1)     //  and keep empty trailing items
  +~- ... .length        //  And append the amount of items minus 1 to the result

Kevin Cruijssen

Posted 2019-03-19T09:28:26.997

Reputation: 67 575

1

Jelly, 7 bytes

ḣḲẈṪ,LƊ

A dyadic Link accepting a list of characters on the left and the 0-indexed index on the right which yields a list of integers, [character, word], again 0-indexed.

Try it online!

Jonathan Allan

Posted 2019-03-19T09:28:26.997

Reputation: 67 804

I think this should return [4, 4] (10-byte fix).

– Erik the Outgolfer – 2019-03-19T17:22:17.047

Thanks @EriktheOutgolfer if we go with 0-indexing it works out nicely for 7. – Jonathan Allan – 2019-03-19T17:54:51.297

1

JavaScript (ES6), 56 bytes

Takes input as (offset)(string).

n=>g=([c,...a],b=i=0)=>n--?g(a,b+!(i+=c!=' '||-i)):[i,b]

Try it online!

Commented

n =>                 // n = desired offset in string
  g = (              // g = recursive function taking:
    [c, ...a],       //   c = current character; a[] = array of remaining characters
    b =              //   b = index of current block
    i = 0            //   i = current position within the current block
  ) =>               //
    n-- ?            // if we haven't reached the desired offset: 
      g(             //   do a recursive call to g:
        a,           //     pass the array of remaining characters
        b + !(       //     update b:
          i +=       //       update i:
            c != ' ' //         increment i if the current character is not a space
            || -i    //         or set i to zero if it is
        )            //     increment b if i was set to zero, or leave it unchanged otherwise
      )              //   end of recursive call
    :                // else:
      [i, b]         //   stop recursion and return [i, b]

Arnauld

Posted 2019-03-19T09:28:26.997

Reputation: 111 334

0

Bash, 66 bytes

z=$(echo ${i:0:o});echo $z|sed 's/^.* //g'|wc -c;set -- $z;echo $#

1-indexed. $i contains the input, and $o contains the offset

Explanation:

z=$(echo ${LDS:0:o});          # delete the rest of the word
echo $z|sed 's/^.* //g'|wc -c; # remove anything up to the last word, and count what's left.
set -- $z;echo $#              # find the number of words after the stuff after the offset is deleted

vityavv

Posted 2019-03-19T09:28:26.997

Reputation: 734

0

Charcoal, 14 bytes

≔⪪…SN θI⟦L⊟θLθ

Try it online! Link is to verbose version of code. Explanation:

≔⪪…SN θ

Truncate the input string to the given length and split on spaces.

I⟦L⊟θLθ

Extract the last string and take its length, then take the number of remaining strings, cast both lengths to string and implicitly print them on separate lines.

Neil

Posted 2019-03-19T09:28:26.997

Reputation: 95 035

0

Retina 0.8.2, 50 bytes

^.+
$*
^(1)*¶((?<-1>.)*).*
$2
^(.*? )*(.*)
$.2,$#1

Try it online! Takes input in the order offset, string. Explanation:

^.+
$*

Convert the offset to unary.

^(1)*¶((?<-1>.)*).*
$2

Truncate the string to the given length. This uses .NET's balancing groups to count the same number of characters in each string.

^(.*? )*(.*)
$.2,$#1

Count the number of spaces and the number of characters after the last space and output them in decimal in reverse order.

Neil

Posted 2019-03-19T09:28:26.997

Reputation: 95 035

0

Ruby, 53 48 bytes

->s,n{t=s[0,n];[n-t[/.* |^/].size,t.count(" ")]}

Try it online!

Kirill L.

Posted 2019-03-19T09:28:26.997

Reputation: 6 693