26
\$\begingroup\$

Given:

  • a blackbox function \$f : \mathbb N \to \mathbb N\$,
  • a list of positive integers \$L\$, and
  • a list of indices \$I\$,

apply \$f(x)\$ to the elements of \$L\$ at the indices specified in \$I\$.

For example, \$f(x) = x^2, L = [7, 6, 3, 9, 1, 5, 2, 8, 4]\$ and \$I = [3, 5, 8]\$ (using 1 indexing), we apply \$f(x)\$ to the 3rd, 5th and 8th elements, yielding \$[7, 6, 9, 9, 1, 5, 2, 64, 4]\$


You may use 0 or 1 indexing for \$I\$. The elements of \$I\$ will be unique (there will be no duplicates), the maximum element of \$I\$ will never exceed the length of \$L\$ (or the length of \$L\$ minus 1, if using 0 indexing) and the minimum will never be below 1 (or 0, for 0 indexing).

Neither \$I\$ nor \$L\$ will ever be empty. \$f\$ will always return a positive integer, and will always take a single positive integer. \$L\$ may be in any order, however, you may decide if \$I\$ is in any specific order (e.g. sorted ascending).

This is , so the shortest code in bytes


Test cases

f(x)
L
I (using 1 indexing)
out

f(x) = x²
[14, 14, 5, 15, 15, 10, 13, 9, 3]
[1, 3, 4, 5, 6, 7]
[196, 14, 25, 225, 225, 100, 169, 9, 3]

f(x) = x+1
[7, 12, 14, 6]
[1, 2, 3, 4]
[8, 13, 15, 7]

f(x) = σ₀(x)+x
[13, 11, 9, 15, 16, 16, 16, 11, 6, 4]
[2, 4, 6, 8, 10]
[13, 13, 9, 19, 16, 21, 16, 13, 6, 7]

where \$\sigma_0(x)\$ is the number of divisors function.

This is a builtin in Jelly. This is a program where you can modify the function \$f\$ in the Header, and it will generate a random L, I then out on separate lines. The final test case is prefilled into the Header.

\$\endgroup\$
8
  • 1
    \$\begingroup\$ I know this is a builtin in multiple languages (Jelly, J and APL come to mind), so I encourage languages where this is a builtin to also include a non-builtin answer \$\endgroup\$ Commented May 5, 2021 at 1:56
  • \$\begingroup\$ Out of interest, how does this work in Jelly? Can't Jelly atoms only work with up to two arguments? \$\endgroup\$
    – rydwolf
    Commented May 5, 2021 at 2:02
  • 2
    \$\begingroup\$ @RedwolfPrograms Jelly uses it's standard functional-programming I/O format and takes \$f\$ as the first link. We then use the ¦ quick, which does exactly as the task asks for, using Ç (previous link) as \$f\$, and to indicate that we use I as the indices link, to result in Ç⁹¦ \$\endgroup\$ Commented May 5, 2021 at 2:05
  • \$\begingroup\$ May I be a Set object instead of a List? \$\endgroup\$
    – user
    Commented May 5, 2021 at 13:00
  • 1
    \$\begingroup\$ @user Yep, that's fine \$\endgroup\$ Commented May 5, 2021 at 13:00

39 Answers 39

8
\$\begingroup\$

Scratch 3, 16 13 blocks

enter image description here Try it online!

Scratch functions can't return, so the function f must edit variable x.

\$\endgroup\$
1
  • 2
    \$\begingroup\$ 134 bytes, or 122 bytes if deleting "I" is acceptable. FYI, in scratchblocks2 notation, your script is 136 bytes. scratch.mit.edu/projects/525982055 \$\endgroup\$
    – Nilster
    Commented May 5, 2021 at 13:53
6
\$\begingroup\$

Python 3, 38 bytes

def f(p,a,i):
	for q in i:a[q]=p(a[q])

Try it online!

-16 bytes using in-place thanks to dingledooper

Python 3, 51 bytes

def f(p,a,i):exec("a[i.pop(0)]=p(a[i[0]]);"*len(i))

Try it online!

Inlining with exec does not make it any shorter. But oh well, it was an idea :P

\$\endgroup\$
4
  • 2
    \$\begingroup\$ The obvious solution of modifying the input in-place should be substantially shorter (like for x in i:a[x]=p(a[x])). \$\endgroup\$ Commented May 5, 2021 at 2:47
  • \$\begingroup\$ @dingledooper ah right, ofc. we're allowed to do that. thanks \$\endgroup\$
    – hyper-neutrino
    Commented May 5, 2021 at 2:49
  • \$\begingroup\$ Though it's still not shorter than the naïve approach, you can reduce the exec approach length by using string formatting: 47 bytes (Note that the indices are taken as a tuple rather than a list) \$\endgroup\$ Commented Oct 5, 2022 at 14:22
  • \$\begingroup\$ the above approach is also 46 bytes in Python 2. \$\endgroup\$ Commented Oct 5, 2022 at 14:26
6
\$\begingroup\$

tinylisp, 104 bytes

(d g(q((L I F _)(i L(c(i(e(h I)_)(F(h L))(h L))(g(t L)(i(e(h I)_)(t I)I)F(a _ 1)))L
(q((F L I)(g L I F 0

The solution is the unnamed lambda function represented by the second line. Uses 0-indexing. Requires that the list of indexes be sorted ascending. Try it online!

Explanation

Our approach is to define a helper function g that takes a fourth argument representing the current index. Then we walk through the list recursively, incrementing the index each time. If the current index matches the head of the list of indices, we call the function on the head of the list of values and cons the result to the recursive call; otherwise, we cons the value unchanged.

Ungolfed:

(load library)
(def _helper
  (lambda (func ls indices index)
    (if ls
      (cons
        (if (equal? (head indices) index)
          (func (head ls))
          (head ls))
        (_helper func
          (tail ls)
          (if (equal? (head indices) index)
            (tail indices)
            indices)
          (add2 index 1)))
      nil)))
(def apply-at-indices
  (lambda (func ls indices) (_helper func ls indices 0)))
\$\endgroup\$
6
\$\begingroup\$

Jelly, 6 bytes

Çṛ¡"Ṭ}

Try it online!

For the sake of not leaving anything too important in the comments, the built-in solution is Ç€⁹¦.

   "      For each element of the left argument and each corresponding element of
    Ṭ}    a list of ones at the indices in the right argument and zeroes elsewhere,
Ç         apply the given function to the left element
  ¡       a number of times equal to
 ṛ        the right element.
   "      (For elements of the left argument past the end of the right argument, leave them unchanged.)
\$\endgroup\$
2
  • 2
    \$\begingroup\$ Strictly speaking, the built-in solution is Ç€⁹¦ as required by certain black-box function implementations, for example this function (which implements triangular numbers in a way that vectorises differently). \$\endgroup\$ Commented May 5, 2021 at 11:45
  • \$\begingroup\$ @JonathanAllan Ah, I always forget that ¦ delegates completely to implicit vectorization--or lack thereof \$\endgroup\$ Commented May 5, 2021 at 12:29
6
\$\begingroup\$

JavaScript (V8), 31 bytes

(a,g,p)=>p.map(i=>a[i]=g(a[i]))

Try it online!

Produces output by modifying the input array in place.

\$\endgroup\$
6
  • 4
    \$\begingroup\$ Why check a[i]? \$\endgroup\$
    – l4m2
    Commented May 5, 2021 at 4:52
  • \$\begingroup\$ I didn't know we were allowed to not return the result (return something else) when using a function.. is it a bit like not displaying the result when using a full program? \$\endgroup\$
    – Kaddath
    Commented May 5, 2021 at 7:32
  • \$\begingroup\$ @l4m2 I hadn't realized the test cases were 1-indexed, so I though invalid indices could be passed. I'll fix that, thanks! \$\endgroup\$
    – rydwolf
    Commented May 5, 2021 at 12:36
  • 3
    \$\begingroup\$ @Kaddath This output method is allowed by default. \$\endgroup\$
    – Arnauld
    Commented May 5, 2021 at 14:12
  • 1
    \$\begingroup\$ OK, I was not contesting the answer, just that I didn't know.. but I reckon it feels weird to me, it's like answering to a question with a full program that displays something else than asked and saying "the result is in this variable" \$\endgroup\$
    – Kaddath
    Commented May 5, 2021 at 14:38
6
\$\begingroup\$

05AB1E, 8 bytes

ZLåÅÏs.V

Try it online! Uses 1-based indexing.

ZLåÅÏs.V  # full program
   ÅÏ     # for elements in...
          # implicit input...
   ÅÏ     # where corresponding element in...
  å       # is...
          # (implicit) each element in...
 L        # [1, 2, 3, ...,
Z         # ..., largest element of...
          # implicit input...
 L        # ]...
  å       # in...
Z         # implicit input...
   ÅÏ     # is 1 replace current element in map with...
      .V  # result of running...
     s    # implicit input...
      .V  # as 05AB1E code
          # (implicit) exit map
          # implicit output
\$\endgroup\$
2
  • \$\begingroup\$ This is 8 bytes, not 9? And you may want to specify you've used 1-based indexing, since 05AB1E is 0-based usually. Nice answer though, +1 from me. :) \$\endgroup\$ Commented Jun 14, 2021 at 10:37
  • \$\begingroup\$ @KevinCruijssen Oops! \$\endgroup\$
    – Makonede
    Commented Jun 14, 2021 at 15:52
5
\$\begingroup\$

J, 13 bytes

1 :'u@{`[`]}'

Try it online!

An adverb modifying the function, taking the 0-based indexes as left arg and L as the right arg. Called like:

indexes  black box function
   v     v  
0 1 2 3 (>: f) 7 12 14 6
               ^
               list L to transform

This is just a very thin wrapper over the gerund form of J's Amend adverb, using { to pluck the values we want to transform and then applying our black box function to them @u.

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

Factor + math.unicode, 50 bytes

[ '[ _ ∈ [ call ] [ drop ] if ] with map-index ]

Try it online!

Explanation:

It's a quotation (anonymous function) that takes a quotation with stack effect ( x -- x ), a sequence of values, and a sequence of 0-indexed indices (in that order) from the data stack as input and leaves a sequence of results on the data stack as output. Assuming [ sq ] { 4 5 } { 0 } is on the data stack when this quotation is called...

  • '[ _ ∈ [ call ] [ drop ] if ] Place a quotation on the stack for with to use later. However, ' starts a fried quotation, which says to slot whatever is on top of the data stack into the _. When _ appears on the left side of a quotation like this, it's just a shorthand for currying a quotation.

    Stack: [ sq ] { 4 5 } [ { 0 } ∈ [ call ] [ drop ] if ]

  • with Partial application on the left. It sticks the [ sq ] into the quotation in such a way that it comes before whatever the following combinator puts on top of the data stack.

    Stack: { 4 5 } [ [ sq ] [ { 0 } ∈ [ call ] [ drop ] if ] swapd call ]

  • map-index Apply a quotation to each element of a sequence, collecting the results into a sequence of the same size. However, map-index will also place the index of the element being mapped on top of the data stack. Inside the quotation during the first iteration now...

    Stack: 4 [ sq ] 0 { 0 } ! element, function, index, indices

  • Shorthand for member? Returns t if the object second from the top is in the sequence on top of the stack.

    Stack: 4 [ sq ] t

  • [ call ] [ drop ] Push some quotations for if to use later.

    Stack: 4 [ sq ] t [ call ] [ drop ]

  • if If third from the top is t, call the first quotation, otherwise call the second.

    Stack: 16

  • Now map-index collects this result into the sequence it's building and proceeds with the next iteration.

    Stack: 5 [ sq ] 1 { 0 }

  • This time, the index is not found in the indices, and so [ sq ] gets dropped instead of called.

    Stack: { 16 5 }

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

APL (Dyalog Unicode), 6 bytes

Full program which is just a thin cover for the built-in @ ("At") operator. Uses whichever indexing APL currently uses (can be 0 or 1).

⎕¨@⎕⊢⎕

Try it online!

⊢⎕ on \$L\$

@⎕ at indices \$I\$

⎕¨ apply \$f\$ to each


Without the built-in:

L←⎕
L[I]←⎕¨L[I←⎕]
L

Try it online!

L←⎕ get \$L\$

L[] extract the following elements from \$L\$:
I←⎕ get \$I\$
⎕¨ get \$f\$ and apply it to each
L[I]← let those values replaces the values in \$L\$ at indices \$I\$

L print the updated \$L\$

\$\endgroup\$
1
  • 1
    \$\begingroup\$ APL continues to impress me. I don't think I've used the @ operator before. \$\endgroup\$ Commented May 6, 2021 at 19:47
5
\$\begingroup\$

R, 38 bytes

function(l,i,f){l[i]=sapply(l[i],f);l}

Try it online!

1-based indices.

If we can assume that f is vectorized (perhaps by use of Vectorize()), then this would be 31 bytes:

function(l,i,f){l[i]=f(l[i]);l}
\$\endgroup\$
4
\$\begingroup\$

Husk, 7 bytes

z?⁰IM€N

Try it online!

Husk probably needs a builtin for this and/or for converting a list of indices into a boolean mask.

Explanation

z?⁰IM€N    Inputs: function, indices, list of values
    M€N    Build a list saying for each natural number if it is present in the indices
z          Pair each element of this list to one of the values and
 ?          if it is truthy
  ⁰          apply the input function
   I        else, apply the identity function (leave the value unchanged)
\$\endgroup\$
4
\$\begingroup\$

Raku, 17 bytes

{@^h[@^i]».=&^f}

Try it online!

0-based indexing. Modifies the input array in-place.

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

Ruby, 33 bytes

->g,l,i{i.map{|x|l[x]=g[l[x]]};l}

Try it online!

\$\endgroup\$
3
  • 1
    \$\begingroup\$ You can drop ;l and state that your function modifies the list in-place, as many other answers are doing. \$\endgroup\$
    – Kirill L.
    Commented May 5, 2021 at 20:52
  • \$\begingroup\$ g[l[x]] really? I was thinking about g(l[x]) or just g l[x] for one less byte. \$\endgroup\$
    – iBug
    Commented May 8, 2021 at 1:48
  • 1
    \$\begingroup\$ @iBug OP's program works with lambdas, which cannot be called like the rest of ruby's methods. With your proposal, ruby would attempt to look up a method named g, of which there is nothing natively defined. Ruby's procs/lambdas must be called with square brackets, or with .call. \$\endgroup\$ Commented May 8, 2021 at 5:18
4
\$\begingroup\$

Haskell, 46 44 bytes

  • -1 byte thanks to Unrelated String, by reminding me that infix is not always better.
  • -1 byte thanks to xnor, by suggesting take/drop instead of splitAt.
foldl.h
h f l i=take i l++f(l!!i):drop(i+1)l

Try it online!

The relevant function is foldl.h, which takes as input f, l, i. The list of indices i is 0-indexed.

How?

h f l i=take i l++f(l!!i):drop(i+1)l

The function h applies f to the i-th element of the list l. Since Haskell is very unappreciative of mutable variables, the only way to do it is concatenating the first i elements of l, then f applied to the i-th element, and finally the rest of l.


foldl.h≡\f l i->foldl(h f)l i

This repeats the previous function for all the indices in the input list i.


Haskell, 33 bytes

foldr.adjust
import Data.Sequence

Try it online!

Basically the same solution, but uses the Seq type from Data.Sequence instead of a List. The import is costly, but the h function from the above solution is already implemented as adjust.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ -1 by not defining infix \$\endgroup\$ Commented May 5, 2021 at 7:15
  • 1
    \$\begingroup\$ @UnrelatedString Well that was unexpected... I guess infix is not always better ^^. Thanks! \$\endgroup\$
    – Delfad0r
    Commented May 5, 2021 at 7:20
  • 2
    \$\begingroup\$ Looks like the more boring take/drop approach is actually 1 shorter: TIO \$\endgroup\$
    – xnor
    Commented May 5, 2021 at 7:26
  • 2
    \$\begingroup\$ This recursive version is also 44, but you might be able to get it shorter using an infix function or something. \$\endgroup\$
    – xnor
    Commented May 5, 2021 at 7:36
4
\$\begingroup\$

BQN, 10 bytes

{𝔽⌾(𝕨⊸⊏)𝕩}

Try it online!

To show off structual under which is a little bit more powerful than J's &. as I found out yesterday. {…} defines a block where we get access (among other things) to 𝕩 as the right argument, 𝕨 the left, and 𝔽 the function that gets modified. So this calls 𝔽⌾(𝕨⊸⊏) with 𝕩. executes the right part, then the left part, and then the inverse of the right part. But unlike &. it also remembers the original array at the inverse step, so it can be used to update the array. So 𝕨⊸⊏ takes the elements of 𝕩 at the indices of 𝕨. On these elements 𝔽 gets called. Then the elements get re-inserted into the original arrays at the indices of 𝕨.

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

x86-16 machine code, 11 bytes

        I_LOOP: 
AD          LODSW                       ; next index into AX 
97          XCHG AX, DI                 ; index in DI 
8A 01       MOV  AL, BYTE PTR[BX+DI]    ; AL = value of L 
FF D5       CALL BP                     ; call BlackBox (tm) function 
88 01       MOV  BYTE PTR[BX+DI], AL    ; value of L = AL 
E2 F6       LOOP I_LOOP                 ; loop until end of I  
C3          RET                         ; return to caller

L list at [BX], I list at [SI] (zero indexed), I length in CX. BlackBox function at [DS:BP], input value/return in AL.

Example run with DEBUG. The "interesting" parts have been highlighted for those who don't speak DEBUG.

enter image description here

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

Lua, 67 bytes

function g(f,l,i)for k,v in pairs(i)do l[v]=f(l[v])end return l end

Try it online!

Uses 1-indexing, i always forget lua uses 1 indexed tables

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

Stax, 14 bytes

Yd{diyI^n_aaMm

Run and debug it

The fully manual method, takes args as block arr arr. Requires 0-indexed indices.

the final result is put on the top of the stack.

The single byte builtin for this which takes args arr arr block is &.

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

Icon, 43 bytes

procedure a(L,I,f)
L[k:=!I]:=f(L[k])&\z
end

Try it online!

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

C#, 50 bytes

(f,L,I)=>L.Select((v,i)=>I.Contains(i+1)?f(v):v);

Online demo: https://dotnetfiddle.net/M4YbOx

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

Scala 3, 50 bytes

f=>I=>_.zipWithIndex.map((?,i)=>if(I(i))f(?)else?)

Try it in Scastie!

Stupid function parameter names ftw! Indexing starts at 0.

f=>  //The blackbox function
I=>  //The Set of indices
 _   //The list of integers
 .zipWithIndex //Zip each element with its index
 .map((?,i)=>  //Map each element `?` and its index `i`
   if(I(i))    //If the Set of indices contains i
    f(?)       //apply f to ?
    else ?     //Otherwise, just return ?
 )
\$\endgroup\$
3
\$\begingroup\$

Java, 42 38 bytes

(a,i,f)->{for(int j:i)a[j]=f.f(a[j]);}

Saved 4 bytes thanks to Olivier Grégoire.

Try it online!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ I'm quite sure you can define your own function interface to reduce apply to only one letter. \$\endgroup\$ Commented May 5, 2021 at 15:45
  • \$\begingroup\$ @OlivierGrégoire Thanks for the tip. \$\endgroup\$ Commented May 5, 2021 at 16:00
3
\$\begingroup\$

C (clang), 54 \$\cdots\$ 52 43 bytes

Saved 9 bytes thanks to att!!!

f(g(),*L,*I,n){for(;n--;)L[*I++]=g(L[*I]);}

Try it online!

Inputs a pointer to a function \$g\$ (inputting an int parameter and returning an int), a pointer to an array of positive integers \$L\$, a pointer to an array of \$0\$-base indices \$I\$, and \$I\$'s length \$n\$ (since pointers in C carry no length info).
Updates \$L\$ in place.

Explanation

f(g(),*L,*I,n)                       // golfed function signature for:  
                                     // int f(
                                     //       int (*g)(int), 
                                     //       int *L, 
                                     //       int *I, 
                                     //       int n  
                                     //      )  
{                                    //  
 for(;n--;)                          // loop over I  
           L[*I  ]=                  // assign L at current index in I
                   g(     );         // to g's return value of  
                     L[*I]           // L at current index in I  
               ++                    // bump I to next index                                                 
\$\endgroup\$
2
  • \$\begingroup\$ f(g(),*L,*I,n){for(;n--;)L[*I++]=g(L[*I]);} for 43 bytes \$\endgroup\$
    – att
    Commented May 6, 2021 at 19:08
  • \$\begingroup\$ @att Nice one - thanks! :D \$\endgroup\$
    – Noodle9
    Commented May 6, 2021 at 19:12
3
\$\begingroup\$

Wolfram Language (Mathematica), 5 bytes

MapAt

Try it online!

Takes input in a slightly annoying format: to apply f to {a,b,c,d,e} at positions {1,3,5} and get {f[a],b,f[c],d,f[e]}, we write

MapAt[f, {a,b,c,d,e}, {{1},{3},{5}}]

Some other varyingly built-in solutions:

  • 18 bytes: MapAt[#,List/@#2]&. Takes input [f,I][L]. The {{1},{3},{5}} syntax bothers me a little, so this lets I be an actual list.
  • 20 19 bytes: Map@#~SubsetMap~#2&. Takes input [f,I][L]. SubsetMap differs from MapAt in that it applies the function to all the elements at some indices at the same time.
  • 27 bytes: (s=#3;s[[#]]=#2/@s[[#]];s)&. Takes input [I,f,L]. Here, we assign the input to a variable, and manually change the values at positions indexed by I.
\$\endgroup\$
3
  • \$\begingroup\$ Inputting as {{1},{3},{5}} is fine, if you want to claim the 5 byter :) \$\endgroup\$ Commented May 6, 2021 at 21:27
  • \$\begingroup\$ I'll take it! :) \$\endgroup\$ Commented May 6, 2021 at 21:30
  • 1
    \$\begingroup\$ The 20-byter can be written infix as Map@#~SubsetMap~#2&. \$\endgroup\$
    – att
    Commented May 7, 2021 at 3:46
2
\$\begingroup\$

Zsh, 36 bytes

for x;grep -xq $[++i] f&&F $x||<<<$x

Try it online!

Expects a function predefined as F, the operand array as command-line arguments, and the indeces from the file f, each on one line.

for x;: for each $x in the command-line arguments:

  • $[++i]: increment $i (which starts at 0 implicitly)
  • grep -xq f: check if $i is present in the file f
    • -q: return success/failure only, don't print matching lines
    • -x: require the whole line to match $i. Otherwise 14 would erroneously match 4
  • &&: if that succeeds:
    • F $x: call F with the argument $x
  • ||: else:
    • <<<$x: just print $x unaltered
\$\endgroup\$
2
\$\begingroup\$

Julia, 19 bytes

f*L*i=L[i]=f.(L[i])

with 1-based indexing

changes L itself as the output

Try it online!

\$\endgroup\$
2
\$\begingroup\$

MMIX, 44 bytes (11 instrs)

Takes f, L, I, len(i); both L and I are lists of uint64_t. f is also necessarily MMIXware argument passing.

(jxd -T)

00000000: fe040004 3b030303 27030308 8e050203  “¥¡¥;¤¤¤'¤¤®⁾¦£¤
00000010: 3b050503 8e070105 bf060000 ae060105  ;¦¦¤⁾¬¢¦Ḃ©¡¡Ẹ©¢¦
00000020: 5b03fffa f6040004 f8000000           [¤”«ẇ¥¡¥ẏ¡¡¡

Disassembly/explanation:

foo GET    $4,rJ
    SLU    $3,$3,3
0H  SUBU   $3,$3,8      // loop: leni--
    LDOU   $5,$2,$3     // j = I[leni]
    SLU    $5,$5,3
    LDOU   $7,$1,$5     // a = L[j]
    PUSHGO $6,$0,0      // b = f(a)
    STOU   $6,$1,$5     // L[j] = b
    PBNZ   $3,0B        // iflikely(leni) goto loop
    PUT    rJ,$4
1H  POP    0,0          // return
\$\endgroup\$
2
\$\begingroup\$

Kotlin, 48 bytes

{f,L,I->L.mapIndexed{i,v->if(i in I)f(v)else v}}

Try it online!

Very straight-forward algorithm. Uses the default rule for submitting lambdas.

\$\endgroup\$
2
\$\begingroup\$

Attache, 2 bytes

On

Try it online!

There's a Builtin for That™.

Another builtin solution, 8 bytes: Over@`->.

Without builtins, 22 bytes

-2 bytes after reading other answers, since this modifies the variable in place. Prepend ;z before the last } to have it also return the value.

${{Set[z,_,y!z@_]}=>x}

Try it online!

23 bytes: ${z&Set&>Tr![x,z[x]|y]}

23 bytes: ${&@(z&Set)![x,z[x]|y]}

31 bytes: ${{[_,y@_][_2in x]}&>@V#Iota!z}

32 bytes: ${{If[_2in x,y@_,_]}&>@V#Iota!z}

33 bytes: ${{[_,_|y][_2in x]}&>Enumerate@z}

33 bytes: ${{[Id,y][_2]!z@_}#x&Has=>Iota@z}

34 bytes: ${{z@_|If[_2,y,Id]}#x&Has=>Iota@z}

34 bytes: ${{If[x&Has!_2,y@_,_]}&>@V#Iota!z}

34 bytes: ${{[Id,y][x&Has!_2]!_}&>@V#Iota!z}

\$\endgroup\$
2
\$\begingroup\$

Elm, 62 bytes

a f i=List.indexedMap(\n->if List.member n i then f else\x->x)

Fairly simple implementation of the function. List.indexedMap expects a function which takes 2 Ints (in this case), but we can also write a function that takes 1 Int and returns an Int -> Int function to save 3 bytes 1 byte over the more straightforward implementation function \n e->if List.member n i then f e else e.

At the cost of 1 byte, the inner function can be written as List.member>>\h->if h i then f else\x->x, and the right operand to >> seems golfable, but I can't quite figure out if that's really the case.

Test Program

Try it here!

import Html exposing (text)

a : (Int -> Int) -> List Int -> List Int -> List Int
a f i=List.indexedMap(\n->if List.member n i then f else\x->x)

main =
  a
    (\x -> x ^ 2)
    [0, 2, 3, 4, 5, 6]
    [14, 14, 5, 15, 15, 10, 13, 9, 3]
  |> List.map String.fromInt
  |> String.join ", "
  |> (\x -> "[" ++ x ++ "]")
  |> text
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.