From c5d0ef8e53608da468f89837a12ab10ecc401978 Mon Sep 17 00:00:00 2001 From: Peter Mikkelsen Date: Fri, 28 Jan 2022 21:49:14 +0000 Subject: =?UTF-8?q?Implement=20rotate=20first=20(=E2=8A=96)=20and=20rotate?= =?UTF-8?q?=20last=20(=E2=8C=BD)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apl9.h | 2 ++ functions.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/apl9.h b/apl9.h index 2a7565f..ef1785b 100644 --- a/apl9.h +++ b/apl9.h @@ -349,6 +349,8 @@ Array *fnExcluding(Array *, Array *); Array *fnCatenateLast(Array *, Array *); Array *fnCatenateFirst(Array *, Array *); Array *fnReshape(Array *, Array *); +Array *fnRotateLast(Array *, Array *); +Array *fnRotateFirst(Array *, Array *); Array *fnSelfReference2(Array *, Array *); /* Monadic operators from operators.c */ diff --git a/functions.c b/functions.c index d96deb6..997c1b4 100644 --- a/functions.c +++ b/functions.c @@ -110,8 +110,8 @@ fndyad dyadfunctiondefs[] = { fnCatenateLast, /* , */ fnCatenateFirst, /* ⍪ */ fnReshape, /* ⍴ */ - 0, /* ⌽ */ - 0, /* ⊖ */ + fnRotateLast, /* ⌽ */ + fnRotateFirst, /* ⊖ */ 0, /* ⍉ */ 0, /* ⍎ */ 0, /* ⍕ */ @@ -1327,6 +1327,57 @@ fnReshape(Array *left, Array *right) return res; } +Array * +fnRotateLast(Array *left, Array *right) +{ + return rundfn(L"⍉(⍉⍺)⊖⍉⍵", nil, nil, left, right); +} + +Array * +fnRotateFirst(Array *left, Array *right) +{ + if(left->type != AtypeInt) + throwerror(nil, EType); + + if(right->rank == 0 || right->size < 2) + return fnSame(right); + + int i, j; + if(left->size == 1 && right->rank != 0){ + vlong v = left->intdata[0]; + left = allocarray(AtypeInt, right->rank-1, right->size / right->shape[0]); + for(i = 0; i < left->rank; i++) + left->shape[i] = right->shape[i+1]; + for(i = 0; i < left->size; i++) + left->intdata[i] = v; + }else + left = fnSame(left); + + if(left->rank != right->rank-1) + throwerror(nil, ERank); + for(i = 0; i < left->rank; i++) + if(left->shape[i] != right->shape[i+1]) + throwerror(nil, EShape); + + int n = right->shape[0]; + for(i = 0; i < left->size; i++) + while(left->intdata[i] < 0) + left->intdata[i] += n; + + Array *result = duparray(right); + for(i = 0; i < n; i++){ + for(j = 0; j < left->size; j++){ + vlong rot = left->intdata[j]; + vlong from = j + ((i+rot)%n)*left->size; + vlong to = j + i*left->size; + memcpy(result->rawdata + to*datasizes[right->type], + right->rawdata + from*datasizes[right->type], + datasizes[right->type]); + } + } + return result; +} + Array * fnSelfReference2(Array *left, Array *right) { -- cgit v1.2.3