2010-06-06 9 views
4

잠시 동안 J 함수를 작업 해봤는데 목록을 스캔하여 연속 된 요소 사본을 별도의 연결된 상자에 넣어야합니다. 나의 노력은 부울 값의 목록을 반환, 불평등에 대한 연속 된 목록 항목을 테스트하는 기능J의 박스형 배열 구조 추상화

(<;. 2) ((2&(~:/\)),1:)

로까지 저를 촬영하고, 때마다 숫자 1이 나타납니다 종료 상자에 목록을 인하했다. 여기에 예제 응용 프로그램입니다 : 다음 입력 인수에 해당 값으로 모든 논리 값을 대체 할 수있는 경우

(<;. 2) ((2&(~:/\)),1:) 1 2 3 3 3 4 1 1 1 
+-+-+-----+-+-----+ 
|1|1|0 0 1|1|0 0 1| 
+-+-+-----+-+-----+ 

작업이 완료 될 것이다. 내가 나를 이상적인 상황에서

final =: mysteryfunction @ (<;. 2) ((2&(~:/\)),1:) 

    final 1 2 3 3 3 4 1 1 1  
+-+-+-----+-+-----+ 
|1|2|3 3 3|4|1 1 1| 
+-+-+-----+-+-----+ 

그런 짓을 할 것입니다 미스터리 기능의 어떤 종류 찾고 있었어요, 추상적으로 (<;. 2) ((2&(~:/\)),1:)에 의해 생성 된 중첩 패턴을 대표하고 원본에 적용 할 수있는 방법이있을 것 입력 목록. (즉, "이 박스형 배열은 첫 번째 요소가 깊이 1에, 두 번째 요소가 깊이 1에, 세 번째, 네 번째 및 다섯 번째 요소가 깊이 1로 상자에 묶여 있습니다. 그리고 상자에 그것을 같은 방법으로 상자. ") 나는 그 행동을 생산하기 위해 ;., S:, L:, L.&.으로 바보짓을 시도했지만 나는별로 행운이 없었다. 이런 일이 발생할 수있는 누락 된 운영자 또는 원칙이 있습니까? 내가이 문제를 너무 과장해서 생각하면 놀라지 않을 것이지만 나는 아이디어가 부족하다.

편집 : 순간

, 내가 가진 유일한 작업 솔루션입니다이 하나 그것은 목록 다음 파멸의 실행 길이 인코딩을 생성하는 두 단계의 과정이다

isduplicate =: ((2&(~:/\)),1:) 

testfun =: 3 : 0 
numduplicates =. #S:0 ((<;.2) isduplicate y) 
distinctboxes =. <"0 (isduplicate#]) y 
numduplicates # each distinctboxes 
) 

상자를 제거하지 않고 인코딩. 저는 원래 J와 Haskell을 사용하여 99 problems을 탠덤로 풀기위한 목적으로이 작업을 수행하고 있기 때문에, 문제 12를 먼저 풀어서 문제 9를 해결하면 문제가 해결됩니다.

답변

2

거의 다 왔어. ~을 추가하고 다른 괄호를 배치하고 바로 그거야 :

은 빠른 설명/그림
(<;.2~ (2&(~:/\) , 1:)) 1 2 3 3 3 4 1 1 1 
┌─┬─┬─────┬─┬─────┐ 
│1│2│3 3 3│4│1 1 1│ 
└─┴─┴─────┴─┴─────┘ 

: 이제

s =: 1 2 3 3 3 4 1 1 1 

    f =: 2&(~:/\) , 1: 
    f s 
1 1 0 0 1 1 0 0 1 

    g =: <;.2 

    (f s) g s 
┌─┬─┬─────┬─┬─────┐ 
│1│2│3 3 3│4│1 1 1│ 
└─┴─┴─────┴─┴─────┘ 

그 최종 (f s) g s이, 때로는 "레프트 훅",라고도 할 수있다 (g~ f) s으로 작성하십시오 (부사 ~은 J에서는 "수동"이라고하고, 하스켈 사본은 flip이됩니다). 또는 암묵으로 이것을 (f g ]) s 포크로 쓸 수도 있습니다.

Chapter 9 of "Learning J"에 대해 자세히 알아 보려면이 주제에 대해 자세히 설명합니다.

업데이트 : 이전에 그룹화 기반 (</.~ (+/\&(1,(2&(~:/\)))))을 사용했으나 원래의 컷 기반 방식은 이보다 더 우아하고 짧습니다. 이것이 바로 레프트 훅에 관한 것이므로 직접 접근 방식을 사용하도록 업데이트했습니다.

+0

그래서 그렇게하는 것입니다! 부울 출력을 사용하여 요소에 J 적용 상자를 만들려고 문서를 둘러 보면서 시간을 보냈습니다. 도와 주셔서 감사합니다. – estanford

+0

반갑습니다. 다시 살펴보면 원래 코드에서 모나드를 사용하는 대신 __dyadic__ cut ('; .2')을 사용한다고 언급했을 것입니다. 마지막으로 말하자면 코드 간결 (그리고 명확성, imo)을 위해서라면 컷 -1 대신에 컷 -2를 쓰면 될 것입니다. 컷 -2 대신에 1을 계속해서 씁니다 :'(<; 1 ~ 1,2 & (~ :/\))'- 멋지고 맛있다! – earl

0

이 기능의 버전은 마음은 더 낫지 만 여전히 완벽한 암묵은 아닙니다. (적어도 어떤 문제는 도로의 다른 문제에 대한 질문을 구걸하지 않습니다.) 일단 루프를 암묵적으로 표현하는 동안 논리를 표현하는 방법을 생각해 보면, 나는 모두 설정 될 것입니다. while 루프 뒤에

NB. boxmerge takes a boxed argument and razes the first two 
NB. elements together into a new box. 
boxmerge =: [:}.]1}~[:<[:;2&{. 

NB. conseq checks to see whether the first two boxes of a boxed 
NB. array contain the same distinct element. (By assumption, each 
NB. box contains only one distinct element.) The name is an 
NB. abbreviation of the question, "consecutive boxes equal?" 
conseq =: [:=/[:~.&.>2&{. 

partfun =: ]`(boxmerge)@.conseq ^:_ 

listpack =: 3 : 0 
mylist =. y 
listbin =. >a: 
while. (mylist -: (>a:)) = 0 do. 
newlist =. partfun mylist 
listbin =. listbin,{. newlist 
mylist =. }. newlist 
end. 
listbin 
) 

아이디어는 목록에 partfun을 적용 할 다른 목록에 머리를 라벨, 원래 목록을 참수하고, 원래 목록이 완전히 비울 때까지 것을 일을 계속하는 것입니다. 나는 암묵적인 표현으로 그 논리를 표현할 수있는 방법이 있어야 할 것처럼 느껴집니다. (실제로, 나는 심지어 온라인 문서에서 그것을 보았다고 생각한다.) 나는 단지 ^:의 적절한 순서를 생각할 수 없다. $:@.은 관 속에 마지막 못을 넣어야한다. .

1

나는 당신이 그것을 overthinking 생각합니다. 완전히 암묵적 일 필요가 있습니까?

s<;.2~ ((2&(~:/\)),1:) s=:1 2 3 3 3 4 1 1 1 
┌─┬─┬─────┬─┬─────┐ 
│1│2│3 3 3│4│1 1 1│ 
└─┴─┴─────┴─┴─────┘ 

가 분명히 그냥 다음 s로 입력 목록을 할당 ;. 표현으로 상품 : 여기에 그냥 함께 던졌다 뭔가.완전히 암묵적이어야 할 필요가 있다면 입력리스트를 불리언 목록으로 래 블링하기 위해 그것을 마사지 할 수 있다고 확신하고 출력을 얻으려면 {. < ;.2 {:과 같은 것을 사용하십시오.